Module: Literal::Properties

Includes:
Types
Included in:
Object
Defined in:
lib/literal/properties.rb

Defined Under Namespace

Classes: DataSchema

Instance Method Summary collapse

Methods included from Types

#_Any, #_Array, #_Boolean, #_Callable, #_Class, #_Constraint, #_Descendant, #_Enumerable, #_Falsy, #_Float, #_Frozen, #_Hash, #_Integer, #_Interface, #_Intersection, #_JSONData, #_Lambda, #_Map, #_Never, #_Nilable, #_Not, #_Procable, #_Range, #_Set, #_Shape, #_String, #_Symbol, #_Truthy, #_Tuple, #_Union, #_Void

Instance Method Details

#__define_literal_methods__(new_property) ⇒ Object (private)



63
64
65
66
67
# File 'lib/literal/properties.rb', line 63

def __define_literal_methods__(new_property)
	__literal_extension__.module_eval(
		__generate_literal_methods__(new_property),
	)
end

#__generate_literal_methods__(new_property) ⇒ Object (private)



77
78
79
80
81
82
83
84
85
# File 'lib/literal/properties.rb', line 77

def __generate_literal_methods__(new_property)
	[
		"# frozen_string_literal: true",
		literal_properties.generate_initializer,
		literal_properties.generate_to_h,
		(new_property.generate_writer_method if new_property.writer),
		(new_property.generate_reader_method if new_property.reader),
	].join("\n")
end

#__literal_extension__Object (private)



69
70
71
72
73
74
75
# File 'lib/literal/properties.rb', line 69

def __literal_extension__
	if defined?(@__literal_extension__)
		@__literal_extension__
	else
		@__literal_extension__ = Module.new
	end
end

#__literal_property_class__Object (private)



59
60
61
# File 'lib/literal/properties.rb', line 59

def __literal_property_class__
	Literal::Property
end

#literal_propertiesObject



47
48
49
50
51
52
53
54
55
# File 'lib/literal/properties.rb', line 47

def literal_properties
	return @literal_properties if defined?(@literal_properties)

	if superclass.is_a?(Literal::Properties)
		@literal_properties = superclass.literal_properties.dup
	else
		@literal_properties = Literal::Properties::Schema.new
	end
end

#prop(name, type, kind = :keyword, reader: false, writer: false, default: nil, &coercion) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/literal/properties.rb', line 9

def prop(name, type, kind = :keyword, reader: false, writer: false, default: nil, &coercion)
	if default && !(Proc === default || default.frozen?)
		raise Literal::ArgumentError.new("The default must be a frozen object or a Proc.")
	end

	unless Literal::Property::VISIBILITY_OPTIONS.include?(reader)
		raise Literal::ArgumentError.new("The reader must be one of #{Literal::Property::VISIBILITY_OPTIONS.map(&:inspect).join(', ')}.")
	end

	unless Literal::Property::VISIBILITY_OPTIONS.include?(writer)
		raise Literal::ArgumentError.new("The writer must be one of #{Literal::Property::VISIBILITY_OPTIONS.map(&:inspect).join(', ')}.")
	end

	if reader && :class == name
		raise Literal::ArgumentError.new(
			"The `:class` property should not be defined as a reader because it breaks Ruby's `Object#class` method, which Literal itself depends on.",
		)
	end

	unless Literal::Property::KIND_OPTIONS.include?(kind)
		raise Literal::ArgumentError.new("The kind must be one of #{Literal::Property::KIND_OPTIONS.map(&:inspect).join(', ')}.")
	end

	property = __literal_property_class__.new(
		name:,
		type:,
		kind:,
		reader:,
		writer:,
		default:,
		coercion:,
	)

	literal_properties << property
	__define_literal_methods__(property)
	include(__literal_extension__)
end