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
30impl Schema for String {
31 fn shape() -> Shape {
32 Shape::Str
33 }
34 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
35 match v {
36 ValueRef::Str(s) if !s.starts_with('@') => Some(s.to_string()),
38 ValueRef::Str(s) => match typed::classify(s) {
39 Ok(typed::Spelled::Plain(s)) => Some(s),
40 Ok(other) => {
41 cx.problem(format!(
42 "expected plain text, found {} (write `@@` for a literal `@`)",
43 other.kind()
44 ));
45 None
46 }
47 Err(e) => {
48 cx.problem_of(crate::diagnostic::Problem::BadTyped, e.to_string());
49 None
50 }
51 },
52 other => {
53 cx.expected(Expected::Str, other);
54 None
55 }
56 }
57 }
58 fn write(&self) -> Value {
59 plain(self)
60 }
61 fn encode(&self, w: &mut Writer) {
62 put_plain(w, self);
63 }
64 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
65 d.str()
67 .filter(|s| !s.starts_with(typed_mark()))
68 .map(str::to_owned)
69 }
70 fn pack(&self, p: &mut Packer) {
71 p.put_str(self);
72 }
73 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
74 u.str().map(str::to_owned)
75 }
76}
77
78impl Schema for std::borrow::Cow<'static, str> {
80 fn shape() -> Shape {
81 Shape::Str
82 }
83 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
84 String::read(v, cx).map(Self::Owned)
85 }
86 fn write(&self) -> Value {
87 plain(self)
88 }
89 fn encode(&self, w: &mut Writer) {
90 put_plain(w, self);
91 }
92 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
93 String::decode(d).map(Self::Owned)
94 }
95 fn pack(&self, p: &mut Packer) {
96 p.put_str(self);
97 }
98 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
99 String::unpack(u).map(Self::Owned)
100 }
101}
102
103impl Schema for std::path::PathBuf {
105 fn shape() -> Shape {
106 Shape::Str
107 }
108 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
109 String::read(v, cx).map(Self::from)
110 }
111 fn write(&self) -> Value {
112 plain(&self.to_string_lossy())
113 }
114 fn encode(&self, w: &mut Writer) {
115 put_plain(w, &self.to_string_lossy());
116 }
117 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
118 String::decode(d).map(Self::from)
119 }
120 fn pack(&self, p: &mut Packer) {
121 p.put_str(&self.to_string_lossy());
122 }
123 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
124 u.str().map(Self::from)
125 }
126}
127
128impl Schema for crate::Atom {
130 fn shape() -> Shape {
131 Shape::Atom
132 }
133 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
134 String::read(v, cx).map(|s| crate::Atom::new(&s))
135 }
136 fn write(&self) -> Value {
137 plain(self.as_str())
138 }
139 fn encode(&self, w: &mut Writer) {
140 put_plain(w, self.as_str());
141 }
142 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
143 d.str()
144 .filter(|s| !s.starts_with(typed_mark()))
145 .map(crate::Atom::new)
146 }
147 fn pack(&self, p: &mut Packer) {
148 p.put_u(u64::from(self.number()));
149 }
150 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
151 crate::Atom::from_number(u32::try_from(u.uint()?).ok()?)
152 }
153}
154
155impl Schema for Box<str> {
156 fn shape() -> Shape {
157 Shape::Str
158 }
159 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
160 String::read(v, cx).map(String::into_boxed_str)
161 }
162 fn write(&self) -> Value {
163 plain(self)
164 }
165 fn encode(&self, w: &mut Writer) {
166 put_plain(w, self);
167 }
168 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
169 String::decode(d).map(String::into_boxed_str)
170 }
171 fn pack(&self, p: &mut Packer) {
172 p.put_str(self);
173 }
174 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
175 u.str().map(Into::into)
176 }
177}
178
179impl Schema for crate::sync::Arc<str> {
181 fn shape() -> Shape {
182 Shape::Str
183 }
184 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
185 String::read(v, cx).map(Into::into)
186 }
187 fn write(&self) -> Value {
188 plain(self)
189 }
190 fn encode(&self, w: &mut Writer) {
191 put_plain(w, self);
192 }
193 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
194 String::decode(d).map(Into::into)
195 }
196 fn pack(&self, p: &mut Packer) {
197 p.put_str(self);
198 }
199 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
200 u.shared_str()
201 }
202}