Class: Textus::Protocol::Format::Yaml
- Inherits:
-
Base
- Object
- Base
- Textus::Protocol::Format::Yaml
show all
- Defined in:
- lib/textus/protocol/format/yaml.rb
Constant Summary
collapse
- RAW_REQUIRED =
%w[ingested_at content_hash].freeze
- RAW_SOURCE_KINDS =
%w[url file asset].freeze
Class Method Summary
collapse
Methods inherited from Base
enforce_name_match!, format_name, nested_ext, rewrite_name
Class Method Details
.data_to_payload(data) ⇒ Object
98
99
100
101
|
# File 'lib/textus/protocol/format/yaml.rb', line 98
def self.data_to_payload(data)
data = data.transform_keys(&:to_s) if data.is_a?(Hash)
{ meta: data["_meta"] || {}, body: nil, content: data["content"] || data }
end
|
.extensions ⇒ Object
66
|
# File 'lib/textus/protocol/format/yaml.rb', line 66
def self.extensions = [".yaml", ".yml"]
|
.nested_glob ⇒ Object
67
|
# File 'lib/textus/protocol/format/yaml.rb', line 67
def self.nested_glob = "**/*.{yaml,yml}"
|
.parse(raw, path: nil) ⇒ Object
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# File 'lib/textus/protocol/format/yaml.rb', line 7
def self.parse(raw, path: nil)
raw = raw.dup.force_encoding(Encoding::UTF_8)
raise BadFrontmatter.new(path, "entry is not valid UTF-8") unless raw.valid_encoding?
begin
parsed = ::YAML.safe_load(raw, permitted_classes: [Date, Time], aliases: false)
rescue Psych::SyntaxError, Psych::AliasesNotEnabled, Psych::DisallowedClass => e
raise BadFrontmatter.new(path, "YAML parse failed: #{e.message}")
end
raise BadFrontmatter.new(path, "YAML top-level must be a mapping") unless parsed.is_a?(Hash)
meta = parsed["_meta"]
fm = meta.is_a?(Hash) ? meta : {}
content_without_meta = parsed.except("_meta")
{ "_meta" => fm, "body" => raw, "content" => content_without_meta }
end
|
.serialize(meta:, body:, content: nil) ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/textus/protocol/format/yaml.rb', line 24
def self.serialize(meta:, body:, content: nil)
if content.is_a?(Hash)
on_disk = meta && !meta.empty? ? { "_meta" => meta }.merge(content) : content
::YAML.dump(on_disk).sub(/\A---\n/, "")
elsif body && !body.to_s.empty?
b = body.to_s
b += "\n" unless b.end_with?("\n")
b
else
raise UsageError.new("yaml serialize requires :content or :body")
end
end
|
.serialize_for_put(meta:, body:, content:, path:) ⇒ Object
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/textus/protocol/format/yaml.rb', line 69
def self.serialize_for_put(meta:, body:, content:, path:)
raise UsageError.new("put for yaml requires content: or body:") if content.nil? && (body.nil? || body.to_s.empty?)
if content.nil?
begin
parsed = parse(body.to_s, path: path)
rescue BadFrontmatter => e
raise BadContent.new(path, "bad_content: #{e.message}")
end
[body.to_s, parsed["_meta"], body.to_s, parsed["content"]]
else
bytes = serialize(meta: meta, body: "", content: content)
[bytes, meta, bytes, content]
end
end
|
.validate_against(schema, parsed) ⇒ Object
37
38
39
|
# File 'lib/textus/protocol/format/yaml.rb', line 37
def self.validate_against(schema, parsed)
schema.validate!(parsed["content"] || {})
end
|
.validate_path_extension(path, nested) ⇒ Object
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/textus/protocol/format/yaml.rb', line 85
def self.validate_path_extension(path, nested)
ext = File.extname(path)
if nested
return if ext == ""
raise UsageError.new("nested yaml path must not have an extension")
end
return if [".yaml", ".yml"].include?(ext)
raise UsageError.new("yaml format requires '.yaml' or '.yml' path (got #{ext.inspect})")
end
|
.validate_raw_entry!(parsed, lane) ⇒ Object
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# File 'lib/textus/protocol/format/yaml.rb', line 44
def self.validate_raw_entry!(parsed, lane)
return unless lane == "raw"
content = parsed["content"] || {}
return if content["superseded_by"]
missing = RAW_REQUIRED.reject { |f| content[f] }
raise Textus::BadContent.new(nil, "raw entry missing required field(s): #{missing.join(", ")}") if missing.any?
source = content["source"] || {}
kind = source["kind"]
unless RAW_SOURCE_KINDS.include?(kind)
raise Textus::BadContent.new(
nil, "raw entry source.kind must be #{RAW_SOURCE_KINDS.join("|")}, got #{kind.inspect}"
)
end
return unless kind == "url" && !source["url"]
raise Textus::BadContent.new(nil, "raw entry with source.kind=url must have source.url")
end
|