feat: metadata, frontmatter, write atomicity should now be in
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
defmodule BDS.Sidecar do
|
||||
@moduledoc false
|
||||
|
||||
alias BDS.Persistence
|
||||
|
||||
@list_item_prefix " - "
|
||||
|
||||
def serialize_document(fields) when is_list(fields) do
|
||||
@@ -21,15 +23,26 @@ defmodule BDS.Sidecar do
|
||||
defp serialize_field({_key, ""}), do: []
|
||||
|
||||
defp serialize_field({key, values}) when is_list(values) do
|
||||
["#{key}:" | Enum.map(values, &" - #{&1}")]
|
||||
["#{key}:" | Enum.map(values, &" - #{serialize_scalar(nil, &1)}")]
|
||||
end
|
||||
|
||||
defp serialize_field({key, value}) when is_boolean(value) do
|
||||
["#{key}: #{if(value, do: "true", else: "false")}"]
|
||||
end
|
||||
|
||||
defp serialize_field({key, value}) when is_integer(value) do
|
||||
rendered =
|
||||
if timestamp_key?(key) do
|
||||
Persistence.timestamp_to_iso8601(value)
|
||||
else
|
||||
Integer.to_string(value)
|
||||
end
|
||||
|
||||
["#{key}: #{rendered}"]
|
||||
end
|
||||
|
||||
defp serialize_field({key, value}) do
|
||||
["#{key}: #{value}"]
|
||||
["#{key}: #{serialize_scalar(key, value)}"]
|
||||
end
|
||||
|
||||
defp parse_lines([], acc), do: acc
|
||||
@@ -46,7 +59,7 @@ defmodule BDS.Sidecar do
|
||||
|
||||
String.contains?(line, ": ") ->
|
||||
[key, raw_value] = String.split(line, ": ", parts: 2)
|
||||
parse_lines(rest, Map.put(acc, key, parse_scalar(raw_value)))
|
||||
parse_lines(rest, Map.put(acc, key, parse_scalar(key, raw_value)))
|
||||
|
||||
true ->
|
||||
parse_lines(rest, acc)
|
||||
@@ -55,7 +68,7 @@ defmodule BDS.Sidecar do
|
||||
|
||||
defp take_list_items([line | rest], items) do
|
||||
if String.starts_with?(line, @list_item_prefix) do
|
||||
value = line |> String.replace_prefix(@list_item_prefix, "") |> parse_scalar()
|
||||
value = line |> String.replace_prefix(@list_item_prefix, "") |> then(&parse_scalar(nil, &1))
|
||||
take_list_items(rest, [value | items])
|
||||
else
|
||||
{items, [line | rest]}
|
||||
@@ -64,14 +77,73 @@ defmodule BDS.Sidecar do
|
||||
|
||||
defp take_list_items([], items), do: {items, []}
|
||||
|
||||
defp parse_scalar("true"), do: true
|
||||
defp parse_scalar("false"), do: false
|
||||
defp parse_scalar(key, value) when is_binary(key) and is_binary(value) do
|
||||
trimmed = String.trim(value)
|
||||
|
||||
defp parse_scalar(value) do
|
||||
cond do
|
||||
timestamp_key?(key) -> Persistence.parse_timestamp(trimmed) || parse_generic_scalar(trimmed)
|
||||
true -> parse_generic_scalar(trimmed)
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_scalar(nil, value) when is_binary(value) do
|
||||
value
|
||||
|> String.trim()
|
||||
|> parse_generic_scalar()
|
||||
end
|
||||
|
||||
defp parse_generic_scalar("true"), do: true
|
||||
defp parse_generic_scalar("false"), do: false
|
||||
|
||||
defp parse_generic_scalar(value) do
|
||||
if Regex.match?(~r/^-?\d+$/, value) do
|
||||
String.to_integer(value)
|
||||
else
|
||||
value
|
||||
parse_string(value)
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_string("\"" <> rest) do
|
||||
rest
|
||||
|> String.trim_trailing("\"")
|
||||
|> String.replace("\\n", "\n")
|
||||
|> String.replace("\\\"", "\"")
|
||||
|> String.replace("\\\\", "\\")
|
||||
end
|
||||
|
||||
defp parse_string(value), do: value
|
||||
|
||||
defp serialize_scalar(_key, value) when is_boolean(value) do
|
||||
if(value, do: "true", else: "false")
|
||||
end
|
||||
|
||||
defp serialize_scalar(key, value) when is_integer(value) do
|
||||
if is_binary(key) and timestamp_key?(key) do
|
||||
Persistence.timestamp_to_iso8601(value)
|
||||
else
|
||||
Integer.to_string(value)
|
||||
end
|
||||
end
|
||||
|
||||
defp serialize_scalar(_key, value) do
|
||||
value
|
||||
|> to_string()
|
||||
|> maybe_quote_string()
|
||||
end
|
||||
|
||||
defp maybe_quote_string(value) do
|
||||
if Regex.match?(~r/^[\p{L}\p{N} ._\/-]+$/u, value) do
|
||||
value
|
||||
else
|
||||
escaped =
|
||||
value
|
||||
|> String.replace("\\", "\\\\")
|
||||
|> String.replace("\"", "\\\"")
|
||||
|> String.replace("\n", "\\n")
|
||||
|
||||
"\"#{escaped}\""
|
||||
end
|
||||
end
|
||||
|
||||
defp timestamp_key?(key), do: String.ends_with?(to_string(key), "_at")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user