Skip to content

Commit 803eadf

Browse files
committed
Add Immutable, DeepImmutable and NilIfEmpty coercions
1 parent 69021aa commit 803eadf

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

lib/literal/coercions.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
# Named coercions for property definitions, passed as the prop’s block:
4+
#
5+
# prop :name, String, &Immutable
6+
# prop :bio, _Nilable(String), &(NilIfEmpty >> Literal::Coercions.Truncated(255))
7+
#
8+
# These are plain procs, so they compose with `Proc#>>`.
9+
module Literal::Coercions
10+
# Shallow: freezes a copy, so the caller’s object is never mutated.
11+
# References held by the value (array elements, hash values) stay mutable.
12+
Immutable = proc { |it| it.frozen? ? it : it.dup.freeze }
13+
14+
# Deep: makes the value Ractor-shareable, freezing the entire object graph.
15+
# Works on a deep copy, so the caller’s object is never mutated. Raises
16+
# Ractor::IsolationError for values that cannot be made shareable (IO,
17+
# Thread, procs capturing mutable state).
18+
DeepImmutable = proc do |it|
19+
Ractor.shareable?(it) ? it : Ractor.make_shareable(it, copy: true)
20+
end
21+
22+
# Converts empty values ("", [], {}) to nil, for optional properties where
23+
# empty input means absent. Everything else passes through untouched.
24+
NilIfEmpty = proc { |it| (it.respond_to?(:empty?) && it.empty?) ? nil : it }
25+
end

lib/literal/properties.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module DocString
99

1010
def self.extended(base)
1111
super
12+
base.include(Literal::Coercions)
1213
base.include(DocString)
1314
base.include(base.__send__(:__literal_extension__))
1415
end

0 commit comments

Comments
 (0)