Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "delegate"
require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/value_semantics"
require "elastic_graph/schema_definition/indexing/field_type/enum"

module ElasticGraph
Expand All @@ -19,6 +20,10 @@ module FieldType
#
# @private
class Enum < DelegateClass(ElasticGraph::SchemaDefinition::Indexing::FieldType::Enum)
prepend ValueSemantics

# @dynamic __getobj__

# @return [Hash<String, ::Object>] additional ElasticGraph metadata to put in the JSON schema for this enum type.
def json_schema_field_metadata_by_field_name
{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "delegate"
require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/value_semantics"
require "elastic_graph/schema_definition/indexing/field_type/scalar"
require "elastic_graph/support/hash_util"

Expand All @@ -19,6 +20,10 @@ module FieldType
#
# @private
class Scalar < DelegateClass(ElasticGraph::SchemaDefinition::Indexing::FieldType::Scalar)
prepend ValueSemantics

# @dynamic __getobj__

# @return [Hash] empty hash, as scalar types have no subfields
def json_schema_field_metadata_by_field_name
{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# frozen_string_literal: true

require "delegate"
require "elastic_graph/json_ingestion/schema_definition/indexing/field_type/value_semantics"
require "elastic_graph/schema_definition/indexing/field_type/union"

module ElasticGraph
Expand All @@ -18,6 +19,10 @@ module FieldType
#
# @private
class Union < DelegateClass(ElasticGraph::SchemaDefinition::Indexing::FieldType::Union)
prepend ValueSemantics

# @dynamic __getobj__

# @return [Hash] empty hash, as union types have no subfields
def json_schema_field_metadata_by_field_name
{}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2024 - 2026 Block, Inc.
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
#
# frozen_string_literal: true

module ElasticGraph
module JSONIngestion
module SchemaDefinition
module Indexing
module FieldType
# Provides value-equality semantics for the JSON-schema-aware field type wrappers that delegate
# to a wrapped core field type without adding any state of their own (`Scalar`, `Enum`, `Union`).
#
# `DelegateClass` defines `==` so that it unwraps only the *left* operand before comparing, which
# means `wrapper == equivalent_wrapper` compares the wrapped object against the right-hand
# *wrapper* (rather than against its wrapped object) and is therefore never equal--even though
# `hash` delegates to the wrapped object and reports them equal. That inconsistency breaks the
# `eql?`/`hash` contract and causes `Set`/`Hash`/`uniq` de-duplication to treat equivalent
# wrappers as distinct. Here we unwrap both sides so two wrappers around equal objects compare
# equal, keeping `==`/`eql?`/`hash` consistent. (`FieldType::Object` solves the same problem with
# its own implementation because it carries additional JSON schema state in its equality.)
#
# @private
module ValueSemantics
# @param other [Object] the object to compare against
# @return [Boolean] true when `other` wraps an equal field type (or is the wrapped field type itself)
def ==(other)
case other
when ValueSemantics
__getobj__ == other.__getobj__
else
super
end
end

def eql?(other)
self == other
end

# @return [Integer] a hash code derived from the wrapped field type
def hash
__getobj__.hash
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ module ElasticGraph
end

class Enum < EnumSupertype
include ValueSemantics

def json_schema_field_metadata_by_field_name: () -> ::Hash[::String, JSONSchemaFieldMetadata]
def format_field_json_schema_customizations: (::Hash[::String, untyped]) -> ::Hash[::String, untyped]
def to_json_schema: () -> ::Hash[::String, untyped]
def __getobj__: () -> ::ElasticGraph::SchemaDefinition::Indexing::FieldType::Enum
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ module ElasticGraph
end

class Scalar < ScalarSupertype
include ValueSemantics

def json_schema_field_metadata_by_field_name: () -> ::Hash[::String, JSONSchemaFieldMetadata]
def format_field_json_schema_customizations: (::Hash[::String, untyped]) -> ::Hash[::String, untyped]
def to_json_schema: () -> ::Hash[::String, untyped]
def __getobj__: () -> ::ElasticGraph::SchemaDefinition::Indexing::FieldType::Scalar
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ module ElasticGraph
end

class Union < UnionSupertype
include ValueSemantics

def self.new: (::ElasticGraph::SchemaDefinition::Indexing::FieldType::Union) -> instance

def json_schema_field_metadata_by_field_name: () -> ::Hash[::String, JSONSchemaFieldMetadata]
def format_field_json_schema_customizations: (::Hash[::String, untyped]) -> ::Hash[::String, untyped]
def to_json_schema: () -> ::Hash[::String, untyped]
def __getobj__: () -> ::ElasticGraph::SchemaDefinition::Indexing::FieldType::Union
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module ElasticGraph
module JSONIngestion
module SchemaDefinition
module Indexing
module FieldType
module ValueSemantics : _Delegator
def ==: (untyped other) -> bool
def eql?: (untyped other) -> bool
def hash: () -> ::Integer
end

interface _Delegator
def __getobj__: () -> untyped

# Provided by `DelegateClass`; `ValueSemantics#==` calls `super` to fall back to it.
def ==: (untyped other) -> bool
end
end
end
end
end
end
Loading
Loading