familia 2.0.0.pre12 → 2.0.0.pre14

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +2 -3
  3. data/CHANGELOG.rst +529 -0
  4. data/CLAUDE.md +1 -1
  5. data/Gemfile +1 -6
  6. data/Gemfile.lock +13 -7
  7. data/README.md +21 -2
  8. data/changelog.d/README.md +5 -5
  9. data/{setup.cfg → changelog.d/scriv.ini} +1 -1
  10. data/docs/guides/Feature-System-Autoloading.md +228 -0
  11. data/docs/guides/time-utilities.md +221 -0
  12. data/docs/migrating/v2.0.0-pre11.md +14 -16
  13. data/docs/migrating/v2.0.0-pre13.md +95 -0
  14. data/docs/migrating/v2.0.0-pre14.md +37 -0
  15. data/examples/autoloader/mega_customer/safe_dump_fields.rb +6 -0
  16. data/examples/autoloader/mega_customer.rb +17 -0
  17. data/examples/safe_dump.rb +1 -1
  18. data/familia.gemspec +1 -0
  19. data/lib/familia/autoloader.rb +53 -0
  20. data/lib/familia/base.rb +5 -0
  21. data/lib/familia/data_type.rb +4 -0
  22. data/lib/familia/encryption/encrypted_data.rb +4 -4
  23. data/lib/familia/encryption/manager.rb +6 -4
  24. data/lib/familia/encryption.rb +1 -1
  25. data/lib/familia/errors.rb +3 -0
  26. data/lib/familia/features/autoloadable.rb +113 -0
  27. data/lib/familia/features/encrypted_fields/concealed_string.rb +4 -2
  28. data/lib/familia/features/expiration.rb +4 -0
  29. data/lib/familia/features/external_identifier.rb +3 -3
  30. data/lib/familia/features/quantization.rb +5 -0
  31. data/lib/familia/features/safe_dump.rb +7 -0
  32. data/lib/familia/features.rb +20 -16
  33. data/lib/familia/field_type.rb +2 -0
  34. data/lib/familia/horreum/core/serialization.rb +3 -3
  35. data/lib/familia/horreum/subclass/definition.rb +3 -4
  36. data/lib/familia/horreum.rb +2 -0
  37. data/lib/familia/json_serializer.rb +70 -0
  38. data/lib/familia/logging.rb +12 -10
  39. data/lib/familia/refinements/logger_trace.rb +57 -0
  40. data/lib/familia/refinements/snake_case.rb +40 -0
  41. data/lib/familia/refinements/time_literals.rb +279 -0
  42. data/lib/familia/refinements.rb +3 -49
  43. data/lib/familia/utils.rb +2 -0
  44. data/lib/familia/validation/{test_helpers.rb → validation_helpers.rb} +2 -2
  45. data/lib/familia/validation.rb +1 -1
  46. data/lib/familia/version.rb +1 -1
  47. data/lib/familia.rb +15 -3
  48. data/try/core/autoloader_try.rb +112 -0
  49. data/try/core/extensions_try.rb +38 -21
  50. data/try/core/familia_extended_try.rb +4 -3
  51. data/try/core/time_utils_try.rb +130 -0
  52. data/try/data_types/datatype_base_try.rb +3 -2
  53. data/try/features/autoloadable/autoloadable_try.rb +61 -0
  54. data/try/features/encrypted_fields/concealed_string_core_try.rb +8 -3
  55. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +59 -17
  56. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +36 -12
  57. data/try/features/external_identifier/external_identifier_try.rb +26 -0
  58. data/try/features/feature_improvements_try.rb +2 -1
  59. data/try/features/real_feature_integration_try.rb +1 -1
  60. data/try/features/safe_dump/safe_dump_autoloading_try.rb +111 -0
  61. data/try/helpers/test_helpers.rb +24 -0
  62. data/try/integration/cross_component_try.rb +3 -1
  63. metadata +34 -6
  64. data/CHANGELOG.md +0 -247
  65. data/lib/familia/core_ext.rb +0 -135
  66. data/lib/familia/features/autoloader.rb +0 -57
@@ -1,135 +0,0 @@
1
- # lib/familia/core_ext.rb
2
-
3
- # Extends the String class with time-related functionality
4
- #
5
- # This implementaton assumes Time::Units and Numeric mixins are available.
6
- #
7
- class String
8
- # Converts a string representation of time to seconds
9
- #
10
- # @example
11
- # "60m".in_seconds #=> 3600.0
12
- #
13
- # @return [Float, nil] The time in seconds, or nil if the string is invalid
14
- def in_seconds
15
- q, u = scan(/([\d.]+)([smhyd])?/).flatten
16
- q &&= q.to_f and u ||= 's'
17
- q&.in_seconds(u)
18
- end
19
- end
20
-
21
- # Extends the Time class with additional time unit functionality
22
- class Time
23
- # Provides methods for working with various time units
24
- module Units
25
- # rubocop:disable Style/SingleLineMethods, Layout/ExtraSpacing
26
-
27
- PER_MICROSECOND = 0.000001
28
- PER_MILLISECOND = 0.001
29
- PER_MINUTE = 60.0
30
- PER_HOUR = 3600.0
31
- PER_DAY = 86_400.0
32
-
33
- # Conversion methods
34
- #
35
- # From other time units -> seconds
36
- #
37
- def microseconds() seconds * PER_MICROSECOND end
38
- def milliseconds() seconds * PER_MILLISECOND end
39
- def seconds() self end
40
- def minutes() seconds * PER_MINUTE end
41
- def hours() seconds * PER_HOUR end
42
- def days() seconds * PER_DAY end
43
- def weeks() seconds * PER_DAY * 7 end
44
- def years() seconds * PER_DAY * 365 end
45
-
46
- # From seconds -> other time units
47
- #
48
- def in_years() seconds / PER_DAY / 365 end
49
- def in_weeks() seconds / PER_DAY / 7 end
50
- def in_days() seconds / PER_DAY end
51
- def in_hours() seconds / PER_HOUR end
52
- def in_minutes() seconds / PER_MINUTE end
53
- def in_milliseconds() seconds / PER_MILLISECOND end
54
- def in_microseconds() seconds / PER_MICROSECOND end
55
-
56
- #
57
- # Converts seconds to a Time object
58
- #
59
- # @return [Time] A Time object representing the seconds
60
- def in_time
61
- Time.at(self).utc
62
- end
63
-
64
- # Converts seconds to the specified time unit
65
- #
66
- # @param u [String, Symbol] The unit to convert to (e.g., 'y', 'w', 'd', 'h', 'm', 'ms', 'us')
67
- # @return [Float] The converted time value
68
- def in_seconds(u = nil)
69
- case u.to_s
70
- when /\A(y)|(years?)\z/
71
- years
72
- when /\A(w)|(weeks?)\z/
73
- weeks
74
- when /\A(d)|(days?)\z/
75
- days
76
- when /\A(h)|(hours?)\z/
77
- hours
78
- when /\A(m)|(minutes?)\z/
79
- minutes
80
- when /\A(ms)|(milliseconds?)\z/
81
- milliseconds
82
- when /\A(us)|(microseconds?)|(μs)\z/
83
- microseconds
84
- else
85
- self
86
- end
87
- end
88
-
89
- # Starring Jennifer Garner, Victor Garber, and Carl Lumbly
90
- alias ms milliseconds
91
- alias μs microseconds
92
- alias second seconds
93
- alias minute minutes
94
- alias hour hours
95
- alias day days
96
- alias week weeks
97
- alias year years
98
-
99
- # rubocop:enable Style/SingleLineMethods, Layout/ExtraSpacing
100
- end
101
- end
102
-
103
- # Extends the Numeric class with time unit and byte conversion functionality
104
- class Numeric
105
- include Time::Units
106
-
107
- # Converts the number to milliseconds
108
- #
109
- # @return [Float] The number in milliseconds
110
- def to_ms
111
- (self * 1000.to_f)
112
- end
113
-
114
- # Converts the number to a human-readable byte representation using binary units
115
- #
116
- # @return [String] A string representing the number in bytes, KiB, MiB, GiB, or TiB
117
- #
118
- # @example
119
- # 1024.to_bytes #=> "1.00 KiB"
120
- # 2_097_152.to_bytes #=> "2.00 MiB"
121
- # 3_221_225_472.to_bytes #=> "3.00 GiB"
122
- #
123
- def to_bytes
124
- units = %w[B KiB MiB GiB TiB]
125
- size = abs.to_f
126
- unit = 0
127
-
128
- while size >= 1024 && unit < units.length - 1
129
- size /= 1024
130
- unit += 1
131
- end
132
-
133
- format('%3.2f %s', size, units[unit])
134
- end
135
- end
@@ -1,57 +0,0 @@
1
- # lib/familia/features/autoloader.rb
2
-
3
- module Familia
4
- module Features
5
- # Autoloader is a mixin that automatically loads feature files from a 'features'
6
- # subdirectory when included. This provides a standardized way to organize and
7
- # auto-load project-specific features.
8
- #
9
- # When included in a module, it automatically:
10
- # 1. Determines the directory containing the module file
11
- # 2. Looks for a 'features' subdirectory in that location
12
- # 3. Loads all *.rb files from that features directory
13
- #
14
- # Example usage:
15
- #
16
- # # apps/api/v2/models/customer/features.rb
17
- # module V2
18
- # class Customer < Familia::Horreum
19
- # module Features
20
- # include Familia::Features::Autoloader
21
- # # Automatically loads all files from customer/features/
22
- # end
23
- # end
24
- # end
25
- #
26
- # This would automatically load:
27
- # - apps/api/v2/models/customer/features/deprecated_fields.rb
28
- # - apps/api/v2/models/customer/features/legacy_support.rb
29
- # - etc.
30
- #
31
- module Autoloader
32
- def self.included(_base)
33
- # Get the file path of the module that's including us.
34
- # `caller_locations(1, 1).first` gives us the location where `include` was called.
35
- # This is a robust way to find the file path, especially for anonymous modules.
36
- calling_location = caller_locations(1, 1)&.first
37
- return unless calling_location
38
-
39
- including_file = calling_location.path
40
-
41
- # Find the features directory relative to the including file
42
- features_dir = File.join(File.dirname(including_file), 'features')
43
-
44
- Familia.ld "[DEBUG] Autoloader: Looking for features in #{features_dir}"
45
-
46
- if Dir.exist?(features_dir)
47
- Dir.glob(File.join(features_dir, '*.rb')).each do |feature_file|
48
- Familia.ld "[DEBUG] Autoloader: Loading feature #{feature_file}"
49
- require feature_file
50
- end
51
- else
52
- Familia.ld "[DEBUG] Autoloader: No features directory found at #{features_dir}"
53
- end
54
- end
55
- end
56
- end
57
- end