mirror of
https://github.com/ditkrg/schemable.git
synced 2026-01-22 22:26:41 +00:00
Add documentation for SchemaModifier class
This commit is contained in:
parent
2e8cb4b610
commit
86e208d7ad
@ -1,9 +1,54 @@
|
||||
module Schemable
|
||||
# The SchemaModifier class provides methods for modifying a given schema.
|
||||
# It includes methods for parsing paths, checking if a path exists in a schema,
|
||||
# deeply merging hashes, adding properties to a schema, and deleting properties from a schema.
|
||||
#
|
||||
# @see Schemable
|
||||
class SchemaModifier
|
||||
|
||||
# Parses a given path into an array of symbols.
|
||||
#
|
||||
# @note This method accepts paths in the following formats:
|
||||
# - 'path.to.property'
|
||||
# - 'path.to.array.[0].property'
|
||||
#
|
||||
# @example
|
||||
# parse_path('path.to.property') #=> [:path, :to, :property]
|
||||
# parse_path('path.to.array.[0].property') #=> [:path, :to, :array, :[0], :property]
|
||||
#
|
||||
# @param path [String] The path to parse.
|
||||
# @return [Array<Symbol>] The parsed path.
|
||||
def parse_path(path)
|
||||
path.split('.').map(&:to_sym)
|
||||
end
|
||||
|
||||
# Checks if a given path exists in a schema.
|
||||
#
|
||||
# @example
|
||||
# schema = {
|
||||
# path: {
|
||||
# type: :object,
|
||||
# properties: {
|
||||
# to: {
|
||||
# type: :object,
|
||||
# properties: {
|
||||
# property: {
|
||||
# type: :string
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# path = 'path.properties.to.properties.property'
|
||||
# incorrect_path = 'path.properties.to.properties.invalid'
|
||||
# path_exists?(schema, path) #=> true
|
||||
# path_exists?(schema, incorrect_path) #=> false
|
||||
#
|
||||
# @param schema [Hash, Array] The schema to check.
|
||||
# @param path [String] The path to check for.
|
||||
# @return [Boolean] True if the path exists in the schema, false otherwise.
|
||||
def path_exists?(schema, path)
|
||||
path_segments = parse_path(path)
|
||||
|
||||
@ -27,9 +72,30 @@ module Schemable
|
||||
true
|
||||
end
|
||||
|
||||
# Deeply merges two hashes.
|
||||
#
|
||||
# @example
|
||||
# destination = { level1: { level2: { level3: 'value' } } }
|
||||
# new_data = { level1_again: 'value' }
|
||||
# deep_merge_hashes(destination, new_data)
|
||||
# #=> { level1: { level2: { level3: 'value' } }, level1_again: 'value' }
|
||||
#
|
||||
# new_destination = [{ object1: 'value' }, { object2: 'value' }]
|
||||
# new_new_data = { object3: 'value' }
|
||||
# deep_merge_hashes(new_destination, new_new_data)
|
||||
# #=> [{ object1: 'value' }, { object2: 'value' }, { object3: 'value' }]
|
||||
#
|
||||
# new_destination = { object1: 'value' }
|
||||
# new_new_data = [{ object2: 'value' }, { object3: 'value' }]
|
||||
# deep_merge_hashes(new_destination, new_new_data)
|
||||
# #=> { object1: 'value', object2: 'value', object3: 'value' }
|
||||
#
|
||||
# @param destination [Hash] The hash to merge into.
|
||||
# @param new_data [Hash] The hash to merge from.
|
||||
# @return [Hash] The merged hashes.
|
||||
def deep_merge_hashes(destination, new_data)
|
||||
if destination.is_a?(Array) && new_data.is_a?(Array)
|
||||
destination.concat(new_data)
|
||||
if destination.is_a?(Hash) && new_data.is_a?(Array)
|
||||
destination.merge(new_data)
|
||||
elsif destination.is_a?(Array) && new_data.is_a?(Hash)
|
||||
destination.push(new_data)
|
||||
elsif destination.is_a?(Hash) && new_data.is_a?(Hash)
|
||||
@ -49,6 +115,30 @@ module Schemable
|
||||
destination
|
||||
end
|
||||
|
||||
# Adds properties to a schema at a given path.
|
||||
#
|
||||
# @example
|
||||
# original_schema = { level1: { level2: { level3: 'value' } } }
|
||||
# new_data = { L3: 'value' }
|
||||
# path = 'level1.level2'
|
||||
# add_properties(original_schema, new_schema, path)
|
||||
# #=> { level1: { level2: { level3: 'value', L3: 'value' } } }
|
||||
#
|
||||
# new_original_schema = { test: [{ object1: 'value' }, { object2: 'value' }] }
|
||||
# new_new_schema = { object2_again: 'value' }
|
||||
# path = 'test.[1]'
|
||||
# add_properties(new_original_schema, new_new_schema, path)
|
||||
# #=> { test: [{ object1: 'value' }, { object2: 'value', object2_again: 'value' }] }
|
||||
#
|
||||
# @param original_schema [Hash] The original schema.
|
||||
# @param new_schema [Hash] The new schema to add.
|
||||
# @param path [String] The path at which to add the new schema.
|
||||
# @note This method accepts paths in the following formats:
|
||||
# - 'path.to.property'
|
||||
# - 'path.to.array.[0].property'
|
||||
# - '.'
|
||||
#
|
||||
# @return [Hash] The modified schema.
|
||||
def add_properties(original_schema, new_schema, path)
|
||||
return deep_merge_hashes(original_schema, new_schema) if path == '.'
|
||||
|
||||
@ -94,6 +184,22 @@ module Schemable
|
||||
original_schema
|
||||
end
|
||||
|
||||
# Deletes properties from a schema at a given path.
|
||||
#
|
||||
# @example
|
||||
# original_schema = { level1: { level2: { level3: 'value' } } }
|
||||
# path = 'level1.level2'
|
||||
# delete_properties(original_schema, path)
|
||||
# #=> { level1: {} }
|
||||
#
|
||||
# new_original_schema = { test: [{ object1: 'value' }, { object2: 'value' }] }
|
||||
# path = 'test.[1]'
|
||||
# delete_properties(new_original_schema, path)
|
||||
# #=> { test: [{ object1: 'value' }] }
|
||||
#
|
||||
# @param original_schema [Hash] The original schema.
|
||||
# @param path [String] The path at which to delete properties.
|
||||
# @return [Hash] The modified schema.
|
||||
def delete_properties(original_schema, path)
|
||||
return original_schema if path == '.'
|
||||
|
||||
|
||||
@ -1,42 +1,9 @@
|
||||
# == SchemaModifier
|
||||
#
|
||||
# This module provides methods for working with Hash/JSON-like schemas.
|
||||
# It includes methods to parse paths, check if a path exists in a schema,
|
||||
# deep merge two hashes or an array and a hash, add properties to a specific
|
||||
# location in a schema, and delete properties at a specified path.
|
||||
#
|
||||
# === Examples
|
||||
#
|
||||
# schema_modifier = Schemable::SchemaModifier.new
|
||||
#
|
||||
# path = "properties.name.items.[0].properties.age"
|
||||
# parsed_path = schema_modifier.parse_path(path)
|
||||
# # => [:properties, :name, :items, :'[0]', :properties, :age]
|
||||
#
|
||||
# schema = { properties: { name: "John" } }
|
||||
# exists = schema_modifier.path_exists?(schema, "properties.name")
|
||||
# # => true
|
||||
#
|
||||
# new_data = { age: 25 }
|
||||
# merged_data = schema_modifier.deep_merge_hashes({ name: "John" }, new_data)
|
||||
# # => { name: "John", age: 25 }
|
||||
#
|
||||
# original_schema = { properties: { name: "John" } }
|
||||
# new_schema = { age: 25 }
|
||||
# updated_schema = schema_modifier.add_properties(original_schema, new_schema, "properties")
|
||||
# # => { properties: { name: "John", age: 25 } }
|
||||
#
|
||||
# schema = { properties: { name: "John", age: 25 } }
|
||||
# path_to_delete = "properties.name.age"
|
||||
# updated_schema = schema_modifier.delete_properties(schema, path_to_delete)
|
||||
# # => { properties: { name: "John" } }
|
||||
#
|
||||
module Schemable
|
||||
class SchemaModifier
|
||||
def parse_path: (path: String) -> Array[Symbol]
|
||||
def path_exists?: (schema: Hash[Symbol, any], path: String) -> bool
|
||||
def deep_merge_hashes: (destination: Hash[Symbol, any], new_data: Hash[Symbol, any]) -> (Hash[Symbol, any] | Array[any])
|
||||
def add_properties: (original_schema: (Hash[Symbol, any] | Array[any]), new_schema: Hash[Symbol, any], path: String) -> (Hash[Symbol, any] | Array[any])
|
||||
def delete_properties: (original_schema: (Hash[Symbol, any] | Array[any]), path: String) -> (Hash[Symbol, any] | Array[any])
|
||||
def deep_merge_hashes: (destination: Hash[Symbol, any], new_data: Hash[Symbol, any]) -> (Hash[Symbol, any])
|
||||
def add_properties: (original_schema: (Hash[Symbol, any]), new_schema: Hash[Symbol, any], path: String) -> (Hash[Symbol, any])
|
||||
def delete_properties: (original_schema: (Hash[Symbol, any]), path: String) -> (Hash[Symbol, any])
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user