substrate_data/schema/plain/
text.rs1use crate::binary::{Decoder, Writer};
4use crate::frame::{Packer, Unpacker};
5use crate::model::borrowed::ValueRef;
6use crate::model::value::Value;
7use crate::schema::{Expected, Reader, Schema, Shape};
8use crate::typed;
9
10fn typed_mark() -> char {
12 crate::names::TYPED
13}
14
15fn plain(s: &str) -> Value {
18 Value::Str(typed::escape_at(s))
19}
20
21fn put_plain(w: &mut Writer, s: &str) {
23 if s.starts_with(typed_mark()) {
24 w.str(&typed::escape_at(s));
25 } else {
26 w.str(s);
27 }
28}
29
30fn put_plain_text(w: &mut crate::text::Writer, s: &str) {
32 if s.starts_with(typed_mark()) {
33 w.str(&typed::escape_at(s));
34 } else {
35 w.str(s);
36 }
37}
38
39impl Schema for String {
40 fn shape() -> Shape {
41 Shape::Str
42 }
43 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
44 match v {
45 ValueRef::Str(s) if !s.starts_with('@') => Some(s.to_string()),
47 ValueRef::Str(s) => match typed::classify(s) {
48 Ok(typed::Spelled::Plain(s)) => Some(s),
49 Ok(other) => {
50 cx.problem(format!(
51 "expected plain text, found {} (write `@@` for a literal `@`)",
52 other.kind()
53 ));
54 None
55 }
56 Err(e) => {
57 cx.problem_of(crate::diagnostic::Problem::BadTyped, e.to_string());
58 None
59 }
60 },
61 other => {
62 cx.expected(Expected::Str, other);
63 None
64 }
65 }
66 }
67 fn write(&self) -> Value {
68 plain(self)
69 }
70 fn write_text(&self, w: &mut crate::text::Writer) {
71 put_plain_text(w, self);
72 }
73 fn encode(&self, w: &mut Writer) {
74 put_plain(w, self);
75 }
76 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
77 d.str()
79 .filter(|s| !s.starts_with(typed_mark()))
80 .map(str::to_owned)
81 }
82 fn pack(&self, p: &mut Packer) {
83 p.put_str(self);
84 }
85 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
86 u.str().map(str::to_owned)
87 }
88}
89
90impl Schema for std::borrow::Cow<'static, str> {
92 fn shape() -> Shape {
93 Shape::Str
94 }
95 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
96 String::read(v, cx).map(Self::Owned)
97 }
98 fn write(&self) -> Value {
99 plain(self)
100 }
101 fn write_text(&self, w: &mut crate::text::Writer) {
102 put_plain_text(w, self);
103 }
104 fn encode(&self, w: &mut Writer) {
105 put_plain(w, self);
106 }
107 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
108 String::decode(d).map(Self::Owned)
109 }
110 fn pack(&self, p: &mut Packer) {
111 p.put_str(self);
112 }
113 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
114 String::unpack(u).map(Self::Owned)
115 }
116}
117
118impl Schema for std::path::PathBuf {
120 fn shape() -> Shape {
121 Shape::Str
122 }
123 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
124 String::read(v, cx).map(Self::from)
125 }
126 fn write(&self) -> Value {
127 plain(&self.to_string_lossy())
128 }
129 fn write_text(&self, w: &mut crate::text::Writer) {
130 put_plain_text(w, &self.to_string_lossy());
131 }
132 fn encode(&self, w: &mut Writer) {
133 put_plain(w, &self.to_string_lossy());
134 }
135 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
136 String::decode(d).map(Self::from)
137 }
138 fn pack(&self, p: &mut Packer) {
139 p.put_str(&self.to_string_lossy());
140 }
141 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
142 u.str().map(Self::from)
143 }
144}
145
146impl Schema for crate::Atom {
148 fn shape() -> Shape {
149 Shape::Atom
150 }
151 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
152 String::read(v, cx).map(|s| crate::Atom::new(&s))
153 }
154 fn write(&self) -> Value {
155 plain(self.as_str())
156 }
157 fn write_text(&self, w: &mut crate::text::Writer) {
158 put_plain_text(w, self.as_str());
159 }
160 fn encode(&self, w: &mut Writer) {
161 put_plain(w, self.as_str());
162 }
163 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
164 d.str()
165 .filter(|s| !s.starts_with(typed_mark()))
166 .map(crate::Atom::new)
167 }
168 fn pack(&self, p: &mut Packer) {
169 p.put_u(u64::from(self.number()));
170 }
171 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
172 crate::Atom::from_number(u32::try_from(u.uint()?).ok()?)
173 }
174}
175
176impl Schema for Box<str> {
177 fn shape() -> Shape {
178 Shape::Str
179 }
180 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
181 String::read(v, cx).map(String::into_boxed_str)
182 }
183 fn write(&self) -> Value {
184 plain(self)
185 }
186 fn write_text(&self, w: &mut crate::text::Writer) {
187 put_plain_text(w, self);
188 }
189 fn encode(&self, w: &mut Writer) {
190 put_plain(w, self);
191 }
192 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
193 String::decode(d).map(String::into_boxed_str)
194 }
195 fn pack(&self, p: &mut Packer) {
196 p.put_str(self);
197 }
198 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
199 u.str().map(Into::into)
200 }
201}
202
203impl Schema for crate::sync::Arc<str> {
205 fn shape() -> Shape {
206 Shape::Str
207 }
208 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
209 String::read(v, cx).map(Into::into)
210 }
211 fn write(&self) -> Value {
212 plain(self)
213 }
214 fn write_text(&self, w: &mut crate::text::Writer) {
215 put_plain_text(w, self);
216 }
217 fn encode(&self, w: &mut Writer) {
218 put_plain(w, self);
219 }
220 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
221 String::decode(d).map(Into::into)
222 }
223 fn pack(&self, p: &mut Packer) {
224 p.put_str(self);
225 }
226 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
227 u.shared_str()
228 }
229}