Module: Philiprehberger::SafeYaml
- Defined in:
- lib/philiprehberger/safe_yaml.rb,
lib/philiprehberger/safe_yaml/loader.rb,
lib/philiprehberger/safe_yaml/schema.rb,
lib/philiprehberger/safe_yaml/version.rb
Defined Under Namespace
Modules: Loader Classes: Error, Schema, SchemaError, SizeError
Constant Summary collapse
- VERSION =
'0.5.0'
Class Method Summary collapse
-
.dump(data, permitted_classes: []) ⇒ String
Safely dumps data to a YAML string with type validation.
-
.dump_file(data, path, permitted_classes: []) ⇒ String
Safely dumps data to a YAML file with type validation.
-
.load(string, **opts) ⇒ Object
Safely loads a YAML string with restricted types.
-
.load_and_validate(string, schema:, **opts) ⇒ Object
Loads and validates a YAML string against a schema in one step.
-
.load_file(path, **opts) ⇒ Object
Safely loads a YAML file with restricted types.
-
.load_with_defaults(string, defaults: {}, **opts) ⇒ Hash
Loads a YAML string and deep merges over default values.
-
.merge(*sources, as_files: nil, **load_opts) ⇒ Hash
Loads multiple YAML sources through the safe loader and deep merges them in order, with later sources winning on conflicts.
-
.sanitize(string) ⇒ String
Sanitizes a YAML string by stripping full-line comments and normalizing whitespace.
Class Method Details
.dump(data, permitted_classes: []) ⇒ String
Safely dumps data to a YAML string with type validation.
44 45 46 |
# File 'lib/philiprehberger/safe_yaml.rb', line 44 def self.dump(data, permitted_classes: []) Loader.dump(data, permitted_classes: permitted_classes) end |
.dump_file(data, path, permitted_classes: []) ⇒ String
Safely dumps data to a YAML file with type validation.
55 56 57 |
# File 'lib/philiprehberger/safe_yaml.rb', line 55 def self.dump_file(data, path, permitted_classes: []) Loader.dump_file(data, path, permitted_classes: permitted_classes) end |
.load(string, **opts) ⇒ Object
Safely loads a YAML string with restricted types.
24 25 26 |
# File 'lib/philiprehberger/safe_yaml.rb', line 24 def self.load(string, **opts) Loader.load(string, **opts) end |
.load_and_validate(string, schema:, **opts) ⇒ Object
Loads and validates a YAML string against a schema in one step.
66 67 68 69 70 |
# File 'lib/philiprehberger/safe_yaml.rb', line 66 def self.load_and_validate(string, schema:, **opts) data = Loader.load(string, **opts) schema.validate!(data) data end |
.load_file(path, **opts) ⇒ Object
Safely loads a YAML file with restricted types.
34 35 36 |
# File 'lib/philiprehberger/safe_yaml.rb', line 34 def self.load_file(path, **opts) Loader.load_file(path, **opts) end |
.load_with_defaults(string, defaults: {}, **opts) ⇒ Hash
Loads a YAML string and deep merges over default values.
87 88 89 90 |
# File 'lib/philiprehberger/safe_yaml.rb', line 87 def self.load_with_defaults(string, defaults: {}, **opts) data = Loader.load(string, **opts) Loader.deep_merge(defaults, data || {}) end |
.merge(*sources, as_files: nil, **load_opts) ⇒ Hash
Loads multiple YAML sources through the safe loader and deep merges them in order, with later sources winning on conflicts.
Each source may be either inline YAML or a path to a YAML file. The following heuristic distinguishes the two: when as_files is nil (the default), a String source is treated as a file path if File.file?(source) returns true, and as inline YAML otherwise. Pass as_files: false to force every source to be parsed as inline YAML, or as_files: true to force every source to be read as a file.
All sources are loaded through Philiprehberger::SafeYaml::Loader.load so size, alias, and permitted-class limits passed via load_opts apply uniformly.
Merge semantics:
-
Nested Hashes are merged recursively.
-
Non-Hash conflicts (including arrays) are replaced by the later source’s value. Arrays are not concatenated.
-
An empty source list returns an empty Hash.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/philiprehberger/safe_yaml.rb', line 119 def self.merge(*sources, as_files: nil, **load_opts) sources.each_with_index.reduce({}) do |acc, (source, idx)| result = load_source(source, idx, as_files, load_opts) unless result.is_a?(Hash) raise ArgumentError, "merge sources must yield Hash, got #{result.class} from source #{idx}" end Loader.deep_merge(acc, result) end end |