castkit 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -1
  3. data/README.md +297 -13
  4. data/castkit.gemspec +3 -0
  5. data/lib/castkit/attribute.rb +82 -59
  6. data/lib/castkit/attributes/definition.rb +64 -0
  7. data/lib/castkit/attributes/options.rb +214 -0
  8. data/lib/castkit/castkit.rb +18 -5
  9. data/lib/castkit/cli/generate.rb +112 -0
  10. data/lib/castkit/cli/list.rb +200 -0
  11. data/lib/castkit/cli/main.rb +43 -0
  12. data/lib/castkit/cli.rb +24 -0
  13. data/lib/castkit/configuration.rb +31 -8
  14. data/lib/castkit/contract/{generic.rb → base.rb} +5 -17
  15. data/lib/castkit/contract/result.rb +2 -2
  16. data/lib/castkit/contract/validator.rb +5 -1
  17. data/lib/castkit/contract.rb +5 -5
  18. data/lib/castkit/core/attributes.rb +87 -44
  19. data/lib/castkit/data_object.rb +11 -30
  20. data/lib/castkit/{ext → dsl}/attribute/access.rb +1 -1
  21. data/lib/castkit/{ext → dsl}/attribute/error_handling.rb +1 -1
  22. data/lib/castkit/{ext → dsl}/attribute/options.rb +1 -1
  23. data/lib/castkit/{ext → dsl}/attribute/validation.rb +3 -3
  24. data/lib/castkit/dsl/attribute.rb +47 -0
  25. data/lib/castkit/{ext → dsl}/data_object/contract.rb +2 -2
  26. data/lib/castkit/{ext → dsl}/data_object/deserialization.rb +6 -2
  27. data/lib/castkit/dsl/data_object/plugins.rb +86 -0
  28. data/lib/castkit/{ext → dsl}/data_object/serialization.rb +1 -1
  29. data/lib/castkit/dsl/data_object.rb +61 -0
  30. data/lib/castkit/inflector.rb +1 -1
  31. data/lib/castkit/plugins.rb +82 -0
  32. data/lib/castkit/serializers/base.rb +94 -0
  33. data/lib/castkit/serializers/default_serializer.rb +156 -0
  34. data/lib/castkit/types/{generic.rb → base.rb} +30 -10
  35. data/lib/castkit/types/boolean.rb +14 -10
  36. data/lib/castkit/types/collection.rb +13 -2
  37. data/lib/castkit/types/date.rb +2 -2
  38. data/lib/castkit/types/date_time.rb +2 -2
  39. data/lib/castkit/types/float.rb +5 -5
  40. data/lib/castkit/types/integer.rb +5 -5
  41. data/lib/castkit/types/string.rb +2 -2
  42. data/lib/castkit/types.rb +1 -1
  43. data/lib/castkit/validators/base.rb +59 -0
  44. data/lib/castkit/validators/boolean_validator.rb +39 -0
  45. data/lib/castkit/validators/collection_validator.rb +29 -0
  46. data/lib/castkit/validators/float_validator.rb +31 -0
  47. data/lib/castkit/validators/integer_validator.rb +31 -0
  48. data/lib/castkit/validators/numeric_validator.rb +2 -2
  49. data/lib/castkit/validators/string_validator.rb +3 -4
  50. data/lib/castkit/version.rb +1 -1
  51. data/lib/castkit.rb +1 -4
  52. data/lib/generators/attribute.rb +39 -0
  53. data/lib/generators/base.rb +97 -0
  54. data/lib/generators/contract.rb +68 -0
  55. data/lib/generators/data_object.rb +48 -0
  56. data/lib/generators/plugin.rb +25 -0
  57. data/lib/generators/serializer.rb +28 -0
  58. data/lib/generators/templates/attribute.rb.tt +21 -0
  59. data/lib/generators/templates/attribute_spec.rb.tt +41 -0
  60. data/lib/generators/templates/contract.rb.tt +26 -0
  61. data/lib/generators/templates/contract_spec.rb.tt +76 -0
  62. data/lib/generators/templates/data_object.rb.tt +17 -0
  63. data/lib/generators/templates/data_object_spec.rb.tt +36 -0
  64. data/lib/generators/templates/plugin.rb.tt +37 -0
  65. data/lib/generators/templates/plugin_spec.rb.tt +18 -0
  66. data/lib/generators/templates/serializer.rb.tt +24 -0
  67. data/lib/generators/templates/serializer_spec.rb.tt +14 -0
  68. data/lib/generators/templates/type.rb.tt +57 -0
  69. data/lib/generators/templates/type_spec.rb.tt +42 -0
  70. data/lib/generators/templates/validator.rb.tt +26 -0
  71. data/lib/generators/templates/validator_spec.rb.tt +23 -0
  72. data/lib/generators/type.rb +29 -0
  73. data/lib/generators/validator.rb +41 -0
  74. metadata +92 -16
  75. data/.rspec_status +0 -196
  76. data/lib/castkit/core/registerable.rb +0 -59
  77. data/lib/castkit/default_serializer.rb +0 -154
  78. data/lib/castkit/serializer.rb +0 -92
  79. data/lib/castkit/validators/base_validator.rb +0 -39
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "set"
4
-
5
- module Castkit
6
- # Abstract base class for defining custom serializers for Castkit::DataObject instances.
7
- #
8
- # Handles circular reference detection and provides a consistent `call` API.
9
- #
10
- # Subclasses must implement an instance method `#call` that returns a hash-like representation.
11
- #
12
- # @example Usage
13
- # class CustomSerializer < Castkit::Serializer
14
- # private
15
- #
16
- # def call
17
- # { type: obj.class.name, data: obj.to_h }
18
- # end
19
- # end
20
- #
21
- # CustomSerializer.call(user_dto)
22
- class Serializer
23
- class << self
24
- # Entrypoint for serializing an object.
25
- #
26
- # @param obj [Castkit::DataObject] the object to serialize
27
- # @param visited [Set, nil] used to track visited object IDs
28
- # @return [Object] result of custom serialization
29
- def call(obj, visited: nil)
30
- new(obj, visited: visited).send(:serialize)
31
- end
32
- end
33
-
34
- # @return [Castkit::DataObject] the object being serialized
35
- attr_reader :obj
36
-
37
- protected
38
-
39
- # Fallback to the default serializer.
40
- #
41
- # @return [Hash]
42
- def serialize_with_default
43
- Castkit::DefaultSerializer.call(obj, visited: visited)
44
- end
45
-
46
- private
47
-
48
- # @return [Set<Integer>] a set of visited object IDs to detect circular references
49
- attr_reader :visited
50
-
51
- # Initializes the serializer instance.
52
- #
53
- # @param obj [Castkit::DataObject]
54
- # @param visited [Set, nil]
55
- def initialize(obj, visited: nil)
56
- @obj = obj
57
- @visited = visited || Set.new
58
- end
59
-
60
- # Subclasses must override this method to implement serialization logic.
61
- #
62
- # @raise [NotImplementedError]
63
- # @return [Object]
64
- def call
65
- raise NotImplementedError, "#{self.class.name} must implement `#call`"
66
- end
67
-
68
- # Wraps the actual serialization logic with circular reference detection.
69
- #
70
- # @return [Object]
71
- # @raise [Castkit::SerializationError] if a circular reference is detected
72
- def serialize
73
- check_circular_reference!
74
- visited << obj.object_id
75
-
76
- result = call
77
- visited.delete(obj.object_id)
78
-
79
- result
80
- end
81
-
82
- # Raises if the object has already been visited (circular reference).
83
- #
84
- # @raise [Castkit::SerializationError]
85
- # @return [void]
86
- def check_circular_reference!
87
- return unless visited.include?(obj.object_id)
88
-
89
- raise Castkit::SerializationError, "Circular reference detected for #{obj.class}"
90
- end
91
- end
92
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Castkit
4
- module Validators
5
- # Abstract base class for all attribute validators.
6
- #
7
- # Validators ensure that a value conforms to specific rules (e.g., type, format, range).
8
- # Subclasses must implement the instance method `#call`.
9
- #
10
- # @abstract
11
- class BaseValidator
12
- class << self
13
- # Invokes the validator with the given arguments.
14
- #
15
- # @param value [Object] the attribute value to validate
16
- # @param options [Hash] the attribute options (e.g., `min`, `max`, `format`)
17
- # @param context [Symbol, String, Hash] the attribute name or context for error reporting
18
- # @return [void]
19
- # @raise [Castkit::AttributeError] if validation fails
20
- def call(value, options:, context:)
21
- new.call(value, options: options, context: context)
22
- end
23
- end
24
-
25
- # Validates the attribute value.
26
- #
27
- # @abstract Override in subclasses.
28
- #
29
- # @param value [Object] the attribute value to validate
30
- # @param options [Hash] the attribute options
31
- # @param context [Symbol, String, Hash] the attribute name or context
32
- # @return [void]
33
- # @raise [NotImplementedError] unless implemented in a subclass
34
- def call(value, options:, context:)
35
- raise NotImplementedError, "#{self.class.name} must implement `#call`"
36
- end
37
- end
38
- end
39
- end