foobara 0.0.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 (359) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +5 -0
  3. data/.rubocop.yml +20 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +10 -0
  6. data/DECISION_LOG.md +220 -0
  7. data/Guardfile +9 -0
  8. data/LICENSE-AGPL.txt +666 -0
  9. data/LICENSE.txt +4 -0
  10. data/README.md +50 -0
  11. data/Rakefile +10 -0
  12. data/concepts.md +153 -0
  13. data/projects/builtin_types/lib/foobara/builtin_types.rb +67 -0
  14. data/projects/builtin_types/src/README.md +140 -0
  15. data/projects/builtin_types/src/array/casters/arrayable.rb +22 -0
  16. data/projects/builtin_types/src/array/supported_processors/element_type_declaration.rb +41 -0
  17. data/projects/builtin_types/src/array/supported_validators/size.rb +43 -0
  18. data/projects/builtin_types/src/associative_array/casters/array.rb +22 -0
  19. data/projects/builtin_types/src/associative_array/supported_processors/key_type_declaration.rb +44 -0
  20. data/projects/builtin_types/src/associative_array/supported_processors/value_type_declaration.rb +44 -0
  21. data/projects/builtin_types/src/atomic_duck.rb +6 -0
  22. data/projects/builtin_types/src/attributes/casters/array.rb +33 -0
  23. data/projects/builtin_types/src/attributes/casters/hash.rb +28 -0
  24. data/projects/builtin_types/src/attributes/supported_processors/element_type_declarations.rb +89 -0
  25. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +40 -0
  26. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/symbolize_defaults.rb +31 -0
  27. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/hash_with_symbolic_keys.rb +37 -0
  28. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/valid_attribute_names.rb +60 -0
  29. data/projects/builtin_types/src/attributes/supported_transformers/defaults.rb +41 -0
  30. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +55 -0
  31. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_of_symbols.rb +47 -0
  32. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_with_valid_attribute_names.rb +54 -0
  33. data/projects/builtin_types/src/attributes/supported_validators/required.rb +51 -0
  34. data/projects/builtin_types/src/big_decimal/casters/integer.rb +21 -0
  35. data/projects/builtin_types/src/big_decimal/casters/string.rb +24 -0
  36. data/projects/builtin_types/src/boolean/casters/numeric.rb +21 -0
  37. data/projects/builtin_types/src/boolean/casters/string_or_symbol.rb +27 -0
  38. data/projects/builtin_types/src/builtin_types.rb +189 -0
  39. data/projects/builtin_types/src/date/casters/hash.rb +23 -0
  40. data/projects/builtin_types/src/date/casters/string.rb +40 -0
  41. data/projects/builtin_types/src/datetime/casters/date.rb +21 -0
  42. data/projects/builtin_types/src/datetime/casters/hash.rb +77 -0
  43. data/projects/builtin_types/src/datetime/casters/seconds_since_epoch.rb +21 -0
  44. data/projects/builtin_types/src/datetime/casters/string.rb +31 -0
  45. data/projects/builtin_types/src/duck/supported_casters/allow_nil.rb +38 -0
  46. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb +29 -0
  47. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb +31 -0
  48. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb +31 -0
  49. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb +43 -0
  50. data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +42 -0
  51. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/cast_one_of.rb +37 -0
  52. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/module_desugarizer.rb +41 -0
  53. data/projects/builtin_types/src/duck/supported_validators/one_of.rb +41 -0
  54. data/projects/builtin_types/src/duck.rb +6 -0
  55. data/projects/builtin_types/src/duckture.rb +6 -0
  56. data/projects/builtin_types/src/email/transformers/downcase.rb +15 -0
  57. data/projects/builtin_types/src/email/validator_base.rb +94 -0
  58. data/projects/builtin_types/src/float/casters/integer.rb +21 -0
  59. data/projects/builtin_types/src/float/casters/string.rb +24 -0
  60. data/projects/builtin_types/src/integer/casters/string.rb +23 -0
  61. data/projects/builtin_types/src/number/supported_validators/max.rb +41 -0
  62. data/projects/builtin_types/src/number/supported_validators/min.rb +41 -0
  63. data/projects/builtin_types/src/string/casters/numeric.rb +21 -0
  64. data/projects/builtin_types/src/string/casters/symbol.rb +21 -0
  65. data/projects/builtin_types/src/string/supported_transformers/downcase.rb +11 -0
  66. data/projects/builtin_types/src/string/supported_validators/matches.rb +41 -0
  67. data/projects/builtin_types/src/string/supported_validators/max_length.rb +37 -0
  68. data/projects/builtin_types/src/symbol/casters/string.rb +21 -0
  69. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/desugarizers/set_size.rb +32 -0
  70. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/type_declaration_validators/size_matches.rb +50 -0
  71. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations.rb +59 -0
  72. data/projects/callback/lib/foobara/callback.rb +1 -0
  73. data/projects/callback/src/block/after.rb +10 -0
  74. data/projects/callback/src/block/around.rb +10 -0
  75. data/projects/callback/src/block/before.rb +10 -0
  76. data/projects/callback/src/block/concerns/block_parameter_not_allowed.rb +21 -0
  77. data/projects/callback/src/block/concerns/block_parameter_required.rb +21 -0
  78. data/projects/callback/src/block/concerns/keyword_argumentable_block.rb +31 -0
  79. data/projects/callback/src/block/concerns/single_argument_block.rb +22 -0
  80. data/projects/callback/src/block/concerns/type.rb +17 -0
  81. data/projects/callback/src/block/error.rb +10 -0
  82. data/projects/callback/src/block.rb +83 -0
  83. data/projects/callback/src/registry/base.rb +90 -0
  84. data/projects/callback/src/registry/chained_conditioned.rb +24 -0
  85. data/projects/callback/src/registry/chained_multiple_action.rb +24 -0
  86. data/projects/callback/src/registry/conditioned.rb +101 -0
  87. data/projects/callback/src/registry/multiple_action.rb +110 -0
  88. data/projects/callback/src/registry/single_action.rb +15 -0
  89. data/projects/callback/src/runner.rb +89 -0
  90. data/projects/callback/src/set.rb +56 -0
  91. data/projects/command/lib/foobara/command.rb +9 -0
  92. data/projects/command/src/command/entity_helpers.rb +145 -0
  93. data/projects/command/src/command.rb +36 -0
  94. data/projects/command/src/concerns/callbacks.rb +93 -0
  95. data/projects/command/src/concerns/description.rb +23 -0
  96. data/projects/command/src/concerns/domain_mappers.rb +35 -0
  97. data/projects/command/src/concerns/entities.rb +88 -0
  98. data/projects/command/src/concerns/errors.rb +181 -0
  99. data/projects/command/src/concerns/errors_type.rb +124 -0
  100. data/projects/command/src/concerns/inputs.rb +59 -0
  101. data/projects/command/src/concerns/inputs_type.rb +58 -0
  102. data/projects/command/src/concerns/namespace.rb +49 -0
  103. data/projects/command/src/concerns/reflection.rb +137 -0
  104. data/projects/command/src/concerns/result.rb +25 -0
  105. data/projects/command/src/concerns/result_type.rb +29 -0
  106. data/projects/command/src/concerns/runtime.rb +119 -0
  107. data/projects/command/src/concerns/state_machine.rb +12 -0
  108. data/projects/command/src/concerns/subcommands.rb +102 -0
  109. data/projects/command/src/concerns/transactions.rb +81 -0
  110. data/projects/command/src/state_machine.rb +57 -0
  111. data/projects/command/src/transformed_command.rb +459 -0
  112. data/projects/command_connectors/lib/foobara/command_connectors.rb +12 -0
  113. data/projects/command_connectors/src/command_connector.rb +401 -0
  114. data/projects/command_connectors/src/command_registry/allowed_rule.rb +29 -0
  115. data/projects/command_connectors/src/command_registry/exposed_command.rb +140 -0
  116. data/projects/command_connectors/src/command_registry/exposed_domain.rb +30 -0
  117. data/projects/command_connectors/src/command_registry/exposed_organization.rb +30 -0
  118. data/projects/command_connectors/src/command_registry.rb +257 -0
  119. data/projects/command_connectors/src/commands/describe.rb +36 -0
  120. data/projects/command_connectors/src/commands/list_commands.rb +51 -0
  121. data/projects/command_connectors/src/commands/ping.rb +21 -0
  122. data/projects/command_connectors/src/commands/query_git_commit_info.rb +81 -0
  123. data/projects/command_connectors/src/request.rb +99 -0
  124. data/projects/command_connectors/src/response.rb +17 -0
  125. data/projects/command_connectors/src/serializer.rb +25 -0
  126. data/projects/command_connectors/src/serializers/aggregate_serializer.rb +32 -0
  127. data/projects/command_connectors/src/serializers/atomic_serializer.rb +25 -0
  128. data/projects/command_connectors/src/serializers/entities_to_primary_keys_serializer.rb +28 -0
  129. data/projects/command_connectors/src/serializers/errors_serializer.rb +18 -0
  130. data/projects/command_connectors/src/serializers/json_serializer.rb +20 -0
  131. data/projects/command_connectors/src/serializers/noop_serializer.rb +20 -0
  132. data/projects/command_connectors/src/serializers/record_store_serializer.rb +31 -0
  133. data/projects/command_connectors/src/serializers/success_serializer.rb +14 -0
  134. data/projects/command_connectors/src/serializers/yaml_serializer.rb +20 -0
  135. data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +35 -0
  136. data/projects/command_connectors/src/transformers/load_aggregates_pre_commit_transformer.rb +36 -0
  137. data/projects/command_connectors_http/lib/foobara/command_connectors_http.rb +6 -0
  138. data/projects/command_connectors_http/src/http/commands/get_options.rb +16 -0
  139. data/projects/command_connectors_http/src/http/commands/help/presenter/command.rb +14 -0
  140. data/projects/command_connectors_http/src/http/commands/help/presenter/domain.rb +14 -0
  141. data/projects/command_connectors_http/src/http/commands/help/presenter/entity.rb +14 -0
  142. data/projects/command_connectors_http/src/http/commands/help/presenter/error.rb +14 -0
  143. data/projects/command_connectors_http/src/http/commands/help/presenter/model.rb +14 -0
  144. data/projects/command_connectors_http/src/http/commands/help/presenter/organization.rb +14 -0
  145. data/projects/command_connectors_http/src/http/commands/help/presenter/processor.rb +14 -0
  146. data/projects/command_connectors_http/src/http/commands/help/presenter/processor_class.rb +14 -0
  147. data/projects/command_connectors_http/src/http/commands/help/presenter/root.rb +14 -0
  148. data/projects/command_connectors_http/src/http/commands/help/presenter/type.rb +14 -0
  149. data/projects/command_connectors_http/src/http/commands/help/presenter.rb +162 -0
  150. data/projects/command_connectors_http/src/http/commands/help/templates/command.html.erb +11 -0
  151. data/projects/command_connectors_http/src/http/commands/help/templates/domain.html.erb +1 -0
  152. data/projects/command_connectors_http/src/http/commands/help/templates/entity.html.erb +1 -0
  153. data/projects/command_connectors_http/src/http/commands/help/templates/error.html.erb +1 -0
  154. data/projects/command_connectors_http/src/http/commands/help/templates/model.html.erb +1 -0
  155. data/projects/command_connectors_http/src/http/commands/help/templates/organization.html.erb +1 -0
  156. data/projects/command_connectors_http/src/http/commands/help/templates/processor.html.erb +1 -0
  157. data/projects/command_connectors_http/src/http/commands/help/templates/processor_class.html.erb +1 -0
  158. data/projects/command_connectors_http/src/http/commands/help/templates/root.html.erb +3 -0
  159. data/projects/command_connectors_http/src/http/commands/help/templates/type.html.erb +1 -0
  160. data/projects/command_connectors_http/src/http/commands/help.rb +98 -0
  161. data/projects/command_connectors_http/src/http/request.rb +98 -0
  162. data/projects/command_connectors_http/src/http/response.rb +14 -0
  163. data/projects/command_connectors_http/src/http.rb +84 -0
  164. data/projects/common/lib/foobara/common.rb +11 -0
  165. data/projects/common/src/data_path.rb +272 -0
  166. data/projects/common/src/error.rb +215 -0
  167. data/projects/common/src/error_collection.rb +97 -0
  168. data/projects/common/src/error_key.rb +168 -0
  169. data/projects/common/src/outcome.rb +101 -0
  170. data/projects/common/src/possible_error.rb +80 -0
  171. data/projects/common/src/runtime_error.rb +24 -0
  172. data/projects/concerns/lib/foobara/concerns.rb +1 -0
  173. data/projects/concerns/src/concern.rb +93 -0
  174. data/projects/delegate/lib/foobara/delegate.rb +1 -0
  175. data/projects/delegate/src/extensions/module.rb +12 -0
  176. data/projects/domain/lib/foobara/domain.rb +25 -0
  177. data/projects/domain/src/domain.rb +65 -0
  178. data/projects/domain/src/domain_mapper/registry.rb +47 -0
  179. data/projects/domain/src/domain_mapper.rb +162 -0
  180. data/projects/domain/src/domain_module_extension.rb +510 -0
  181. data/projects/domain/src/extensions/foobara.rb +69 -0
  182. data/projects/domain/src/global_domain.rb +14 -0
  183. data/projects/domain/src/global_organization.rb +12 -0
  184. data/projects/domain/src/is_manifestable.rb +68 -0
  185. data/projects/domain/src/manifestable.rb +12 -0
  186. data/projects/domain/src/module_extension.rb +122 -0
  187. data/projects/domain/src/organization.rb +52 -0
  188. data/projects/domain/src/organization_module_extension.rb +50 -0
  189. data/projects/entity/lib/foobara/entity.rb +27 -0
  190. data/projects/entity/src/concerns/associations.rb +241 -0
  191. data/projects/entity/src/concerns/attributes.rb +170 -0
  192. data/projects/entity/src/concerns/callbacks.rb +97 -0
  193. data/projects/entity/src/concerns/initialization.rb +127 -0
  194. data/projects/entity/src/concerns/persistence.rb +142 -0
  195. data/projects/entity/src/concerns/primary_key.rb +43 -0
  196. data/projects/entity/src/concerns/queries.rb +96 -0
  197. data/projects/entity/src/concerns/reflection.rb +51 -0
  198. data/projects/entity/src/concerns/transactions.rb +31 -0
  199. data/projects/entity/src/concerns/types.rb +31 -0
  200. data/projects/entity/src/entity.rb +61 -0
  201. data/projects/entity/src/extensions/builtin_types/entity/casters/hash.rb +33 -0
  202. data/projects/entity/src/extensions/builtin_types/entity/validators/attributes_declaration.rb +32 -0
  203. data/projects/entity/src/extensions/builtin_types/entity.rb +6 -0
  204. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/attributes_handler_desugarizer.rb +14 -0
  205. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/hash_desugarizer.rb +43 -0
  206. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/model_class_desugarizer.rb +21 -0
  207. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/primary_key_desugarizer.rb +19 -0
  208. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/to_type_transformer.rb +64 -0
  209. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_is_symbol.rb +35 -0
  210. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_present.rb +27 -0
  211. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_references_attribute.rb +36 -0
  212. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration.rb +11 -0
  213. data/projects/entity/src/new_prepend.rb +21 -0
  214. data/projects/entity/src/not_found_error.rb +72 -0
  215. data/projects/enumerated/lib/foobara/enumerated.rb +1 -0
  216. data/projects/enumerated/src/accessors.rb +61 -0
  217. data/projects/enumerated/src/values.rb +121 -0
  218. data/projects/foobara/lib/foobara/all.rb +44 -0
  219. data/projects/in_memory_crud_driver/lib/foobara/in_memory_crud_driver.rb +3 -0
  220. data/projects/in_memory_crud_driver/src/in_memory.rb +10 -0
  221. data/projects/in_memory_crud_driver_minimal/lib/foobara/in_memory_crud_driver_minimal.rb +1 -0
  222. data/projects/in_memory_crud_driver_minimal/src/in_memory_minimal.rb +113 -0
  223. data/projects/manifest/lib/foobara/manifest.rb +4 -0
  224. data/projects/manifest/src/foobara/manifest/array.rb +13 -0
  225. data/projects/manifest/src/foobara/manifest/attributes.rb +40 -0
  226. data/projects/manifest/src/foobara/manifest/base_manifest.rb +161 -0
  227. data/projects/manifest/src/foobara/manifest/command.rb +59 -0
  228. data/projects/manifest/src/foobara/manifest/domain.rb +43 -0
  229. data/projects/manifest/src/foobara/manifest/entity.rb +35 -0
  230. data/projects/manifest/src/foobara/manifest/error.rb +33 -0
  231. data/projects/manifest/src/foobara/manifest/model.rb +43 -0
  232. data/projects/manifest/src/foobara/manifest/organization.rb +45 -0
  233. data/projects/manifest/src/foobara/manifest/possible_error.rb +30 -0
  234. data/projects/manifest/src/foobara/manifest/processor.rb +11 -0
  235. data/projects/manifest/src/foobara/manifest/processor_class.rb +11 -0
  236. data/projects/manifest/src/foobara/manifest/root_manifest.rb +112 -0
  237. data/projects/manifest/src/foobara/manifest/type.rb +86 -0
  238. data/projects/manifest/src/foobara/manifest/type_declaration.rb +117 -0
  239. data/projects/model/lib/foobara/model.rb +23 -0
  240. data/projects/model/src/concerns/reflection.rb +22 -0
  241. data/projects/model/src/concerns/types.rb +104 -0
  242. data/projects/model/src/extensions/builtin_types/model/casters/hash.rb +23 -0
  243. data/projects/model/src/extensions/builtin_types/model/transformers/mutable.rb +26 -0
  244. data/projects/model/src/extensions/builtin_types/model/validators/attributes_declaration.rb +33 -0
  245. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +24 -0
  246. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +32 -0
  247. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +119 -0
  248. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +57 -0
  249. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +21 -0
  250. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +37 -0
  251. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +25 -0
  252. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +46 -0
  253. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +28 -0
  254. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +27 -0
  255. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +31 -0
  256. data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -0
  257. data/projects/model/src/model.rb +320 -0
  258. data/projects/monorepo/lib/foobara/monorepo/project.rb +52 -0
  259. data/projects/monorepo/lib/foobara/monorepo.rb +63 -0
  260. data/projects/namespace/lib/foobara/namespace.rb +4 -0
  261. data/projects/namespace/src/ambiguous_registry.rb +104 -0
  262. data/projects/namespace/src/base_registry.rb +66 -0
  263. data/projects/namespace/src/extensions/module.rb +5 -0
  264. data/projects/namespace/src/is_namespace.rb +352 -0
  265. data/projects/namespace/src/namespace/lookup_mode.rb +41 -0
  266. data/projects/namespace/src/namespace.rb +61 -0
  267. data/projects/namespace/src/namespace_helpers.rb +273 -0
  268. data/projects/namespace/src/prefixless_registry.rb +54 -0
  269. data/projects/namespace/src/scoped.rb +113 -0
  270. data/projects/namespace/src/unambiguous_registry.rb +65 -0
  271. data/projects/persistence/lib/foobara/persistence.rb +22 -0
  272. data/projects/persistence/src/entity_attributes_crud_driver.rb +241 -0
  273. data/projects/persistence/src/entity_base/table.rb +14 -0
  274. data/projects/persistence/src/entity_base/transaction/concerns/entity_callback_handling.rb +157 -0
  275. data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +83 -0
  276. data/projects/persistence/src/entity_base/transaction/concerns/transaction_tracking.rb +53 -0
  277. data/projects/persistence/src/entity_base/transaction/state_machine.rb +27 -0
  278. data/projects/persistence/src/entity_base/transaction.rb +163 -0
  279. data/projects/persistence/src/entity_base/transaction_table/concerns/queries.rb +42 -0
  280. data/projects/persistence/src/entity_base/transaction_table/concerns/record_tracking.rb +134 -0
  281. data/projects/persistence/src/entity_base/transaction_table.rb +620 -0
  282. data/projects/persistence/src/entity_base.rb +114 -0
  283. data/projects/persistence/src/persistence.rb +172 -0
  284. data/projects/state_machine/lib/foobara/state_machine.rb +1 -0
  285. data/projects/state_machine/src/callbacks.rb +158 -0
  286. data/projects/state_machine/src/log_entry.rb +13 -0
  287. data/projects/state_machine/src/state_machine.rb +91 -0
  288. data/projects/state_machine/src/sugar.rb +125 -0
  289. data/projects/state_machine/src/transition_log.rb +19 -0
  290. data/projects/state_machine/src/validations.rb +69 -0
  291. data/projects/thread_parent/lib/foobara/thread_parent.rb +1 -0
  292. data/projects/thread_parent/src/thread_parent.rb +38 -0
  293. data/projects/type_declarations/lib/foobara/type_declarations.rb +131 -0
  294. data/projects/type_declarations/src/attributes.rb +34 -0
  295. data/projects/type_declarations/src/caster.rb +7 -0
  296. data/projects/type_declarations/src/desugarizer.rb +25 -0
  297. data/projects/type_declarations/src/dsl/attributes.rb +199 -0
  298. data/projects/type_declarations/src/element_processor.rb +7 -0
  299. data/projects/type_declarations/src/error_extension.rb +73 -0
  300. data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +31 -0
  301. data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +37 -0
  302. data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +22 -0
  303. data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +36 -0
  304. data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +14 -0
  305. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +28 -0
  306. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +20 -0
  307. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +25 -0
  308. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +34 -0
  309. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +60 -0
  310. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +21 -0
  311. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +16 -0
  312. data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +75 -0
  313. data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +23 -0
  314. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +30 -0
  315. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +24 -0
  316. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +13 -0
  317. data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +29 -0
  318. data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +65 -0
  319. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +32 -0
  320. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +39 -0
  321. data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +26 -0
  322. data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +28 -0
  323. data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +24 -0
  324. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +26 -0
  325. data/projects/type_declarations/src/processor.rb +7 -0
  326. data/projects/type_declarations/src/to_type_transformer.rb +11 -0
  327. data/projects/type_declarations/src/transformer.rb +7 -0
  328. data/projects/type_declarations/src/type_builder.rb +112 -0
  329. data/projects/type_declarations/src/type_declaration_error.rb +9 -0
  330. data/projects/type_declarations/src/type_declaration_handler.rb +120 -0
  331. data/projects/type_declarations/src/type_declaration_handler_registry.rb +27 -0
  332. data/projects/type_declarations/src/type_declaration_validator.rb +19 -0
  333. data/projects/type_declarations/src/type_declarations.rb +128 -0
  334. data/projects/type_declarations/src/typed_transformer.rb +89 -0
  335. data/projects/type_declarations/src/validator.rb +7 -0
  336. data/projects/type_declarations/src/with_registries.rb +41 -0
  337. data/projects/types/lib/foobara/types.rb +11 -0
  338. data/projects/types/src/element_processor.rb +7 -0
  339. data/projects/types/src/extensions/error.rb +32 -0
  340. data/projects/types/src/type/concerns/reflection.rb +79 -0
  341. data/projects/types/src/type/concerns/supported_processor_registration.rb +56 -0
  342. data/projects/types/src/type.rb +375 -0
  343. data/projects/types/src/types.rb +4 -0
  344. data/projects/value/lib/foobara/value.rb +7 -0
  345. data/projects/value/src/caster.rb +84 -0
  346. data/projects/value/src/data_error.rb +27 -0
  347. data/projects/value/src/processor/casting.rb +123 -0
  348. data/projects/value/src/processor/multi.rb +63 -0
  349. data/projects/value/src/processor/pipeline.rb +27 -0
  350. data/projects/value/src/processor/runner.rb +38 -0
  351. data/projects/value/src/processor/selection.rb +90 -0
  352. data/projects/value/src/processor.rb +358 -0
  353. data/projects/value/src/transformer.rb +84 -0
  354. data/projects/value/src/validator.rb +53 -0
  355. data/projects/version/lib/foobara/version.rb +4 -0
  356. data/projects/version/src/version.rb +5 -0
  357. data/projects/weak_object_set/lib/foobara/weak_object_set.rb +3 -0
  358. data/projects/weak_object_set/src/weak_object_set.rb +163 -0
  359. metadata +445 -0
@@ -0,0 +1,28 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module Casters
5
+ class Hash < Value::Caster
6
+ def applicable?(value)
7
+ value.is_a?(::Hash) && value.keys.all? { |key| key.is_a?(::Symbol) || key.is_a?(::String) }
8
+ end
9
+
10
+ def applies_message
11
+ "be a hash with symbolizable keys"
12
+ end
13
+
14
+ def cast(hash)
15
+ keys = hash.keys
16
+ non_symbolic_keys = keys.reject { |key| key.is_a?(::Symbol) }
17
+
18
+ if non_symbolic_keys.empty?
19
+ hash
20
+ else
21
+ Util.symbolize_keys(hash)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,89 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedProcessors
5
+ class ElementTypeDeclarations < TypeDeclarations::ElementProcessor
6
+ class UnexpectedAttributesError < Foobara::Value::DataError
7
+ class << self
8
+ def context_type_declaration
9
+ {
10
+ unexpected_attributes: [:symbol],
11
+ allowed_attributes: [:symbol]
12
+ }
13
+ end
14
+
15
+ def fatal?
16
+ true
17
+ end
18
+ end
19
+ end
20
+
21
+ def applicable?(value)
22
+ value.is_a?(::Hash)
23
+ end
24
+
25
+ def allowed_attributes
26
+ @allowed_attributes ||= declaration_data.keys
27
+ end
28
+
29
+ def process_value(attributes_hash)
30
+ attributes_hash = Util.deep_dup(attributes_hash)
31
+
32
+ unexpected_attributes = attributes_hash.keys - allowed_attributes
33
+
34
+ unless unexpected_attributes.empty?
35
+ return Outcome.error(
36
+ build_error(
37
+ attributes_hash,
38
+ message: "Unexpected attributes #{
39
+ unexpected_attributes
40
+ }. Expected only #{allowed_attributes}",
41
+ context: {
42
+ unexpected_attributes:,
43
+ allowed_attributes:
44
+ }
45
+ )
46
+ )
47
+ end
48
+
49
+ errors = []
50
+
51
+ attributes_hash.each_pair do |attribute_name, attribute_value|
52
+ attribute_type_declaration = element_type_declarations[attribute_name]
53
+ attribute_type = type_for_declaration(attribute_type_declaration)
54
+ attribute_outcome = attribute_type.process_value(attribute_value)
55
+
56
+ if attribute_outcome.success?
57
+ attributes_hash[attribute_name] = attribute_outcome.result
58
+ else
59
+ attribute_outcome.each_error do |error|
60
+ error.path = [attribute_name, *error.path]
61
+
62
+ errors << error
63
+ end
64
+ end
65
+ end
66
+
67
+ Outcome.new(result: attributes_hash, errors:)
68
+ end
69
+
70
+ def possible_errors
71
+ possibilities = [*super]
72
+
73
+ element_type_declarations.each_pair do |attribute_name, attribute_declaration|
74
+ attribute_type = type_for_declaration(attribute_declaration)
75
+
76
+ attribute_type.possible_errors.each do |possible_error|
77
+ possible_error = possible_error.dup
78
+ possible_error.prepend_path!(attribute_name)
79
+ possibilities << possible_error
80
+ end
81
+ end
82
+
83
+ possibilities
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,40 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedTransformers
5
+ class Defaults < Value::Transformer
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module Desugarizers
9
+ class MoveDefaultsFromElementTypesToRoot < TypeDeclarations::Desugarizer
10
+ def applicable?(value)
11
+ value.is_a?(::Hash) && value[:type] == :attributes
12
+ end
13
+
14
+ def desugarize(rawish_type_declaration)
15
+ defaults = rawish_type_declaration[:defaults]
16
+ defaults = defaults ? defaults.dup : {}
17
+
18
+ element_type_declarations = rawish_type_declaration[:element_type_declarations]
19
+
20
+ element_type_declarations.each_pair do |attribute_name, attribute_type_declaration|
21
+ if attribute_type_declaration.is_a?(Hash) && attribute_type_declaration.key?(:default)
22
+ default = attribute_type_declaration[:default]
23
+ element_type_declarations[attribute_name] = attribute_type_declaration.except(:default)
24
+ defaults.merge!(attribute_name => default)
25
+ end
26
+ end
27
+
28
+ rawish_type_declaration[:defaults] = defaults unless defaults.empty?
29
+
30
+ rawish_type_declaration
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedTransformers
5
+ class Defaults < Value::Transformer
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module Desugarizers
9
+ class SymbolizeDefaults < TypeDeclarations::Desugarizer
10
+ def applicable?(value)
11
+ value.is_a?(::Hash) && value[:type] == :attributes && value[:defaults]
12
+ end
13
+
14
+ def desugarize(rawish_type_declaration)
15
+ defaults = rawish_type_declaration[:defaults]
16
+
17
+ if defaults.any? { |key, _| key.is_a?(::String) }
18
+ rawish_type_declaration[:defaults] = defaults.transform_keys(&:to_sym)
19
+ end
20
+
21
+ rawish_type_declaration
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedTransformers
5
+ class Defaults < Value::Transformer
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module TypeDeclarationValidators
9
+ class HashWithSymbolicKeys < TypeDeclarations::TypeDeclarationValidator
10
+ class InvalidDefaultValuesGivenError < Value::DataError
11
+ class << self
12
+ def message
13
+ "Defaults should be a hash with symbolic keys"
14
+ end
15
+ end
16
+ end
17
+
18
+ def applicable?(strict_type_declaration)
19
+ strict_type_declaration.is_a?(Hash) && strict_type_declaration.key?(:defaults)
20
+ end
21
+
22
+ def validation_errors(strict_type_declaration)
23
+ defaults = strict_type_declaration[:defaults]
24
+
25
+ unless defaults.is_a?(Hash) && Util.all_symbolic_keys?(defaults)
26
+ build_error(context: { attribute_name: :defaults, value: defaults })
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,60 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedTransformers
5
+ class Defaults < Value::Transformer
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module TypeDeclarationValidators
9
+ class ValidAttributeNames < TypeDeclarations::TypeDeclarationValidator
10
+ class InvalidDefaultValueGivenError < Value::DataError
11
+ class << self
12
+ def context_type_declaration
13
+ {
14
+ invalid_key: :symbol,
15
+ valid_attribute_names: [:symbol],
16
+ defaults: :attributes
17
+ }
18
+ end
19
+
20
+ def fatal?
21
+ # Since there could be multiple bad defaults
22
+ true
23
+ end
24
+ end
25
+ end
26
+
27
+ def applicable?(strict_type_declaration)
28
+ defaults = strict_type_declaration[:defaults]
29
+
30
+ defaults.is_a?(::Hash) && Util.all_symbolic_keys?(defaults)
31
+ end
32
+
33
+ def validation_errors(strict_type_declaration)
34
+ defaults = strict_type_declaration[:defaults]
35
+
36
+ valid_attribute_names = strict_type_declaration[:element_type_declarations].keys
37
+
38
+ # TODO: this should be one error instead of multiple
39
+ defaults.keys.map do |key|
40
+ unless valid_attribute_names.include?(key)
41
+ build_error(
42
+ message: "#{key} is not a valid default key, expected one of #{valid_attribute_names}",
43
+ context: {
44
+ invalid_key: key,
45
+ valid_attribute_names:,
46
+ defaults:
47
+ }
48
+ )
49
+ end
50
+ end.compact
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedTransformers
5
+ class Defaults < Value::Transformer
6
+ class << self
7
+ def requires_parent_declaration_data?
8
+ true
9
+ end
10
+ end
11
+
12
+ def transform(attributes_hash)
13
+ to_apply = {}
14
+
15
+ defaults.each_pair do |attribute_name, default|
16
+ if attributes_hash.key?(attribute_name)
17
+ value = attributes_hash[attribute_name]
18
+
19
+ if value.nil?
20
+ allow_nil = parent_declaration_data[:element_type_declarations][attribute_name][:allow_nil]
21
+
22
+ unless allow_nil
23
+ to_apply[attribute_name] = default
24
+ end
25
+ end
26
+ else
27
+ to_apply[attribute_name] = default
28
+ end
29
+ end
30
+
31
+ if to_apply.empty?
32
+ attributes_hash
33
+ else
34
+ attributes_hash.merge(to_apply)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,55 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedValidators
5
+ class Required < TypeDeclarations::Validator
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module Desugarizers
9
+ class MoveRequiredFromElementTypesToRoot < TypeDeclarations::Desugarizer
10
+ def applicable?(value)
11
+ value.is_a?(::Hash) && value[:type] == :attributes
12
+ end
13
+
14
+ def desugarize(rawish_type_declaration)
15
+ required_attributes = Util.array(rawish_type_declaration[:required])
16
+ # TODO: move this to a transformer...
17
+ required_attributes = required_attributes.map do |value|
18
+ if value.is_a?(::String)
19
+ value.to_sym
20
+ else
21
+ value
22
+ end
23
+ end
24
+
25
+ element_type_declarations = rawish_type_declaration[:element_type_declarations]
26
+
27
+ element_type_declarations.each_pair do |attribute_name, attribute_type_declaration|
28
+ if attribute_type_declaration.is_a?(::Hash) && attribute_type_declaration.key?(:required)
29
+ is_required = attribute_type_declaration[:required]
30
+
31
+ if [true, false].include?(is_required)
32
+ element_type_declarations[attribute_name] = attribute_type_declaration.except(:required)
33
+
34
+ if is_required
35
+ required_attributes << attribute_name
36
+ else
37
+ required_attributes.delete(attribute_name)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ rawish_type_declaration[:required] = required_attributes unless required_attributes.empty?
44
+
45
+ rawish_type_declaration
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,47 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedValidators
5
+ class Required < TypeDeclarations::Validator
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module TypeDeclarationValidators
9
+ class ArrayOfSymbols < TypeDeclarations::TypeDeclarationValidator
10
+ class InvalidRequiredAttributesValuesGivenError < Value::DataError
11
+ class << self
12
+ def message
13
+ "Required should be an array of symbols"
14
+ end
15
+
16
+ def context_type_declaration
17
+ {
18
+ value: :duck
19
+ }
20
+ end
21
+ end
22
+ end
23
+
24
+ def applicable?(strict_type_declaration)
25
+ strict_type_declaration.key?(:required)
26
+ end
27
+
28
+ def validation_errors(strict_type_declaration)
29
+ required = strict_type_declaration[:required]
30
+
31
+ unless required.is_a?(::Array) && Util.all_symbolic_elements?(required)
32
+ build_error
33
+ end
34
+ end
35
+
36
+ def error_context(value)
37
+ { value: }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedValidators
5
+ class Required < TypeDeclarations::Validator
6
+ module TypeDeclarationExtension
7
+ module ExtendAttributesTypeDeclaration
8
+ module TypeDeclarationValidators
9
+ class ArrayWithValidAttributeNames < TypeDeclarations::TypeDeclarationValidator
10
+ class InvalidRequiredAttributeNameGivenError < Value::DataError
11
+ class << self
12
+ def context_type_declaration
13
+ {
14
+ invalid_required_attribute_name: :symbol,
15
+ valid_attribute_names: [:symbol],
16
+ required: [:symbol]
17
+ }
18
+ end
19
+ end
20
+ end
21
+
22
+ def applicable?(strict_type_declaration)
23
+ required = strict_type_declaration[:required]
24
+
25
+ required.is_a?(::Array) && Util.all_symbolic_elements?(required)
26
+ end
27
+
28
+ def validation_errors(strict_type_declaration)
29
+ required = strict_type_declaration[:required]
30
+
31
+ valid_attribute_names = strict_type_declaration[:element_type_declarations].keys
32
+
33
+ required.map do |key|
34
+ unless valid_attribute_names.include?(key)
35
+ build_error(
36
+ message: "#{key} is not a valid default key, expected one of #{valid_attribute_names}",
37
+ context: {
38
+ invalid_required_attribute_name: key,
39
+ valid_attribute_names:,
40
+ required:
41
+ }
42
+ )
43
+ end
44
+ end.compact
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,51 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Attributes
4
+ module SupportedValidators
5
+ class Required < TypeDeclarations::Validator
6
+ class MissingRequiredAttributeError < Foobara::Value::DataError
7
+ class << self
8
+ def context_type_declaration
9
+ {
10
+ attribute_name: :symbol
11
+ }
12
+ end
13
+
14
+ def fatal?
15
+ true
16
+ end
17
+ end
18
+ end
19
+
20
+ def applicable?(value)
21
+ value.is_a?(::Hash)
22
+ end
23
+
24
+ def required_attribute_names
25
+ required
26
+ end
27
+
28
+ def validation_errors(attributes_hash)
29
+ required_attribute_names.map do |required_attribute_name|
30
+ unless attributes_hash.key?(required_attribute_name)
31
+ build_error(
32
+ message: "Missing required attribute #{required_attribute_name}",
33
+ context: { attribute_name: required_attribute_name },
34
+ path: [required_attribute_name]
35
+ )
36
+ end
37
+ end.compact
38
+ end
39
+
40
+ def possible_errors
41
+ required_attribute_names.map do |required_attribute_name|
42
+ possible_error = PossibleError.new(error_class, processor: self)
43
+ possible_error.prepend_path!(required_attribute_name)
44
+ possible_error
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module BigDecimal
4
+ module Casters
5
+ class Integer < Value::Caster
6
+ def applicable?(value)
7
+ value.is_a?(::Integer)
8
+ end
9
+
10
+ def applies_message
11
+ "be a an Integer"
12
+ end
13
+
14
+ def cast(integer)
15
+ BigDecimal(integer)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module BigDecimal
4
+ module Casters
5
+ class String < Value::Caster
6
+ FLOAT_REGEX = /^-?\d+(\.\d+)?([eE]-?\d+)?$/
7
+
8
+ def applicable?(value)
9
+ value.is_a?(::String) && value =~ FLOAT_REGEX
10
+ end
11
+
12
+ def applies_message
13
+ "be a string of digits with one decimal point optionally amongst " \
14
+ "them and optionally with a minus sign in front and optionally an exponent denoted with e"
15
+ end
16
+
17
+ def cast(string)
18
+ BigDecimal(string)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Boolean
4
+ module Casters
5
+ class Numeric < Value::Caster
6
+ def applicable?(value)
7
+ [0, 1].include?(value)
8
+ end
9
+
10
+ def applies_message
11
+ "be 0 or 1"
12
+ end
13
+
14
+ def cast(value)
15
+ !value.zero?
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Boolean
4
+ module Casters
5
+ class StringOrSymbol < Value::Caster
6
+ TRUE_VALUES = Set["true", "t", "1", "yes", "y"]
7
+ FALSE_VALUES = Set["false", "f", "0", "no", "n"]
8
+ ALLOWED_VALUES = TRUE_VALUES | FALSE_VALUES
9
+
10
+ def applicable?(value)
11
+ value = value.to_s if value.is_a?(::Symbol)
12
+
13
+ value.is_a?(::String) && ALLOWED_VALUES.include?(value.downcase)
14
+ end
15
+
16
+ def applies_message
17
+ "be a String or Symbol that is one of #{ALLOWED_VALUES.join(", ")} (case-insensitive)"
18
+ end
19
+
20
+ def cast(value)
21
+ TRUE_VALUES.include?(value.to_s.downcase)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end