field_struct 0.15.0

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/AGENTS.md +58 -0
  3. data/CHANGELOG.md +653 -0
  4. data/CODE_OF_CONDUCT.md +132 -0
  5. data/README.md +645 -0
  6. data/UPGRADING.md +743 -0
  7. data/USAGE.md +820 -0
  8. data/docs/getting_started.md +337 -0
  9. data/lib/field_struct/base.rb +1316 -0
  10. data/lib/field_struct/error.rb +48 -0
  11. data/lib/field_struct/errors.rb +103 -0
  12. data/lib/field_struct/field.rb +179 -0
  13. data/lib/field_struct/metadata.rb +331 -0
  14. data/lib/field_struct/model_name.rb +48 -0
  15. data/lib/field_struct/rbs.rb +299 -0
  16. data/lib/field_struct/registry.rb +85 -0
  17. data/lib/field_struct/scaffold.rb +331 -0
  18. data/lib/field_struct/types/array.rb +156 -0
  19. data/lib/field_struct/types/base.rb +162 -0
  20. data/lib/field_struct/types/big_decimal.rb +78 -0
  21. data/lib/field_struct/types/binary.rb +38 -0
  22. data/lib/field_struct/types/boolean.rb +126 -0
  23. data/lib/field_struct/types/date.rb +158 -0
  24. data/lib/field_struct/types/datetime.rb +163 -0
  25. data/lib/field_struct/types/email.rb +49 -0
  26. data/lib/field_struct/types/float.rb +80 -0
  27. data/lib/field_struct/types/immutable_string.rb +18 -0
  28. data/lib/field_struct/types/integer.rb +133 -0
  29. data/lib/field_struct/types/nested.rb +82 -0
  30. data/lib/field_struct/types/preset_resolver.rb +37 -0
  31. data/lib/field_struct/types/rfc3339_format.rb +197 -0
  32. data/lib/field_struct/types/string.rb +73 -0
  33. data/lib/field_struct/types/symbol.rb +38 -0
  34. data/lib/field_struct/types/temporal_parser.rb +93 -0
  35. data/lib/field_struct/types/time.rb +168 -0
  36. data/lib/field_struct/types/time_format_resolver.rb +54 -0
  37. data/lib/field_struct/types/union.rb +96 -0
  38. data/lib/field_struct/types/url.rb +46 -0
  39. data/lib/field_struct/types/uuid.rb +46 -0
  40. data/lib/field_struct/types/value.rb +24 -0
  41. data/lib/field_struct/types/zone_option.rb +267 -0
  42. data/lib/field_struct/version.rb +7 -0
  43. data/lib/field_struct.rb +159 -0
  44. data/sig/field_struct.rbs +2845 -0
  45. data/skills/field-struct/SKILL.md +183 -0
  46. metadata +139 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1ebdb327e4ca03c28fdf761a124ac8e69ebfe053ff6415e7b09f76b95316e4d8
4
+ data.tar.gz: 2728f46e3b638b3a5a602bd2a3094a82663f9ec92e4de32e0b393c4d6fa1d62e
5
+ SHA512:
6
+ metadata.gz: 770377dc647aeba20b93759308fee46dcf5a52d0bd51324f65779a769415e0adc57bce23a3dae18814519c9d96d3ef520ede07b50173cde18dcf7819c246898c
7
+ data.tar.gz: 4beb8782870e63c29f2f0d204d5f771ac70337a26663af8e808ac470c02023ddb94bbe0822dc744d968a1532dd00fba3d0bc48b46d1b28e9ff0634bcec5c202b
data/AGENTS.md ADDED
@@ -0,0 +1,58 @@
1
+ # Working with the field_struct gem
2
+
3
+ This repo provides **FieldStruct** — a Ruby gem for typed POROs (declared fields with
4
+ coercion and validation). This file routes AI coding agents to the right docs and the
5
+ things most often gotten wrong. (For *contributing to the gem itself*, see
6
+ `CLAUDE.md`.)
7
+
8
+ ## Read these
9
+
10
+ - **[`docs/getting_started.md`](docs/getting_started.md)** — how to use it in a repo
11
+ (general Ruby + Rails): a task→API map, an error→fix table, and a worked example.
12
+ - **[`USAGE.md`](USAGE.md)** — dense reference: every type, option, and macro.
13
+ - **[`README.md`](README.md)** — feature overview.
14
+ - **[`UPGRADING.md`](UPGRADING.md)** — moving to a newer version: symptom, Find, fix.
15
+ - `skills/field-struct/SKILL.md` — the bundled Claude Code skill.
16
+
17
+ ## The six gotchas
18
+
19
+ 1. **Setters are permissive** — `user.age = "30"` is valid (the type coerces). Don't "fix" it.
20
+ 2. **`required` ≠ non-nil at runtime** — an invalid instance can hold `nil`. Gate on `valid?`.
21
+ 3. **Whitespace-only strings count as missing** for `:string` and its subtypes.
22
+ 4. **`:array` needs `of:`; `:union` needs `of: [...]`** (≥2 members).
23
+ 5. **Option scoping**: `format:`→string/date-ish, `enum:`→string/symbol, `in:`→numeric/temporal, `round:`→float/decimal, `base:`→integer, `strict:`→string-shaped/integer, `zone:`→time/datetime, `values:`→boolean, `element:`→array (a Hash of the element type's options); `sensitive:` works on any type. A misapplied known option raises at class load and names the types it applies to; an *unknown* option passes through onto the Field untouched (kept for downstream tooling). You don't have to memorize this table — ask the type (next section).
24
+ 6. **`valid?` is computed on assignment, not on read.** Mutating a nested struct or an array element in place doesn't refresh the parent's errors. Assign the field again (or use `with`) to re-validate. See [USAGE](USAGE.md#validity-is-computed-on-assignment-shallow-valid-staleness).
25
+
26
+ ## Upgrading
27
+
28
+ Moving a project to a newer field_struct? [`UPGRADING.md`](UPGRADING.md) lists every
29
+ visible change since 0.10 with a symptom, a Find command, and a fix. Procedure:
30
+
31
+ 1. Read your old version from `Gemfile.lock` (`field_struct (x.y.z)`) and the target
32
+ tag. Open `UPGRADING.md` (repo root, or `bundle show field_struct` after bumping)
33
+ and read every section from the one after your old version to the target.
34
+ 2. Bump the Gemfile tag. If the project uses **actionable** >= 1.6, field_struct
35
+ must be >= 0.12 (its gemspec says so); if `oj` is pinned below 3.11.2, loosen it.
36
+ `bundle update field_struct`.
37
+ 3. Check `rg --pcre2-version` works in your shell. Run the Find of every entry
38
+ the TL;DR lists as **silent**, from the project root, and read each hit using the
39
+ entry's narrowing rule. Run the other entries' Finds only for code the suite
40
+ doesn't reach; those changes raise or fail a spec.
41
+ 4. Apply the matching **Fix** to each real hit. Don't change behaviour you weren't
42
+ asked to — e.g. keep a renamed reserved field's wire name with `serialize :json`.
43
+ 5. Run the full suite. Match each failure against UPGRADING.md's symptom index and
44
+ fix it; if nothing matches, follow its "If something else breaks" section.
45
+ 6. If the project generates RBS with `FieldStruct::RBS.generate`, or with a task that
46
+ wraps it (`rg -n 'FieldStruct::RBS' lib Rakefile`), regenerate it and run Steep if
47
+ the project does.
48
+ 7. Report: old → new version, each entry that applied (file:line, fix), each Find
49
+ with no hits, and anything left unexplained.
50
+
51
+ ## Fast paths
52
+
53
+ - Bootstrap a model from a JSON sample: `FieldStruct::Scaffold.from_json(json)`.
54
+ - See a model's shape without reading source: `pp Klass.metadata.to_h` (structured), or `puts Klass.describe` (readable — fields, types, and what each accepts).
55
+ - Ask a type what options it accepts (name, value shape, presets): `FieldStruct.types.lookup(:date).option_schema`.
56
+ - Type your models for Steep/Solargraph: `FieldStruct::RBS.generate(Klass)`.
57
+ - "Update" an immutable or frozen instance: `record.with(field: value)` returns a changed copy.
58
+ - Payment/API input: `unknown_attributes :raise` on every struct that reads it, `strict: true` on money and id fields, `sensitive: true` on card data. See [USAGE](USAGE.md#payment-and-api-boundaries-unknown_attributes-raise).