bridge_types/lib.rs
1use std::borrow::Cow;
2use std::fmt::Display;
3
4/// A slosh [`Value`](../slvm/value/enum.Value.html) that can potentially be represented as a rust value.
5/// Marker traits
6pub trait BridgedType {}
7
8/// An [`Option`] value that contains a [`BridgedType`] can be represented as a rust value.
9impl<T> BridgedType for Option<T> where T: BridgedType {}
10
11/// A [`Result`] value that contains a [`BridgedType`] can be represented as a rust value.
12impl<T, U> BridgedType for Result<T, U> where T: BridgedType {}
13
14/// A [`Vec`] that contains a [`BridgedType`] can be represented as a rust value.
15impl<T> BridgedType for Vec<T> where T: BridgedType {}
16
17/// Public type used by rust native -> slosh bridge macro to represent
18/// arguments in slosh that correspond to variadic functions in rust
19///
20/// Type is useful so it is possible to write rust native functions
21/// that appear in slosh as functions that can receive any number of arguments.
22pub type VarArgs<T> = Vec<T>;
23
24/// [`Value`]: ../slvm/value/enum.Value.html
25/// [`Value::String`]: ../slvm/value/enum.Value.html#variant.String
26/// Type to hold anything in Slosh that can be represented as a [`String`].
27///
28/// Public type used by rust native -> slosh bridge macro to represent
29/// arguments that can be loosely cast to strings. Unlike the [`String`]
30/// and [`&str`] types, in slosh there are various types that can be
31/// represented as strings. When the rust native function doesn't
32/// require *strict* type checking on whether or not the [`Value::String`]
33/// type is passed in use this function.
34///
35/// Can represent SlRefInto [`Value`] types:
36/// - String
37/// - CodePoint
38/// - CharCluster
39/// - CharClusterLong
40/// - Symbol
41/// - Keyword
42/// - StringConst
43///
44/// Always does an allocation and returns a [`Value::String`] type.
45pub type LooseString<'a> = Cow<'a, str>;
46
47/// [`Value`]: ../slvm/value/enum.Value.html
48/// [`Value::Float`]: ../slvm/value/enum.Value.html#variant.Float
49/// Type to hold anything in Slosh that can be represented as a slosh float value: `[u8; 7]`.
50///
51/// Public type used by rust native -> slosh bridge macro to represent
52/// arguments that can be loosely cast to an int.
53///
54/// Can represent SlRefInto [`Value`] types:
55/// - Byte
56/// - Int
57/// - Float
58/// - String
59/// - CodePoint
60/// - CharCluster
61/// - CharClusterLong
62/// - Symbol
63/// - Keyword
64/// - StringConst
65///
66/// Always returns a [`Value::Float`] type.
67pub struct LooseFloat(pub [u8; 7]);
68
69impl From<LooseFloat> for [u8; 7] {
70 fn from(value: LooseFloat) -> Self {
71 value.0
72 }
73}
74
75impl From<[u8; 7]> for LooseFloat {
76 fn from(value: [u8; 7]) -> Self {
77 LooseFloat(value)
78 }
79}
80
81/// [`Value`]: ../slvm/value/enum.Value.html
82/// [`Value::Symbol`]: ../slvm/value/enum.Value.html#variant.Symbol
83/// Type to hold anything in Slosh that can be represented as a slosh symbol: u32.
84///
85/// Public type used by rust native -> slosh bridge macro to represent
86/// arguments that reference a valid symbol.
87///
88/// Can represent SlRefInto [`Value`] types:
89/// - Symbol
90///
91/// Always returns a [`Value::Symbol`] type.
92pub struct Symbol(u32);
93
94impl From<u32> for Symbol {
95 fn from(value: u32) -> Self {
96 Self(value)
97 }
98}
99
100impl From<Symbol> for u32 {
101 fn from(value: Symbol) -> Self {
102 value.0
103 }
104}
105
106/// [`Value`]: ../slvm/value/enum.Value.html
107/// [`Value::Symbol`]: ../slvm/value/enum.Value.html#variant.Symbol
108/// Type to hold anything in Slosh that can be represented as a slosh symbol, however, this
109/// type, in contrast to [`Symbol`] does need to do some allocations, specifically when
110/// using [`SlFrom`]. Not a huge penalty but worth mentioning if unnecessary.
111///
112/// Public type used by rust native -> slosh bridge macro to represent
113/// arguments that reference a valid symbol.
114///
115/// Can represent SlRefInto [`Value`] types:
116/// - Symbol
117///
118/// Always returns a [`Value::Symbol`] type.
119pub struct SymbolAsString(String);
120
121impl AsRef<str> for SymbolAsString {
122 fn as_ref(&self) -> &str {
123 &self.0
124 }
125}
126
127impl From<String> for SymbolAsString {
128 fn from(value: String) -> Self {
129 Self(value)
130 }
131}
132
133impl From<SymbolAsString> for String {
134 fn from(value: SymbolAsString) -> Self {
135 value.0
136 }
137}
138
139/// [`Value`]: ../slvm/value/enum.Value.html
140/// Type to hold anything in Slosh that can be represented as slosh int value: `[u8; 7]`.
141///
142/// Public type used by rust native -> slosh bridge macro to represent
143/// arguments that can be loosely cast to an int.
144///
145/// Can represent SlRefInto [`Value`] types:
146/// - Byte
147/// - Int
148/// - Float
149/// - String
150/// - CodePoint
151/// - CharCluster
152/// - CharClusterLong
153/// - Symbol
154/// - Keyword
155/// - StringConst
156///
157/// Always returns a [`Value`]`::Int` type.
158pub struct LooseInt(pub [u8; 7]);
159
160impl From<LooseInt> for [u8; 7] {
161 fn from(value: LooseInt) -> Self {
162 value.0
163 }
164}
165
166impl From<[u8; 7]> for LooseInt {
167 fn from(value: [u8; 7]) -> Self {
168 LooseInt(value)
169 }
170}
171
172/// [`Value`]: ../slvm/value/enum.Value.html
173/// [`Value::CodePoint`]: ../slvm/value/enum.Value.html#variant.CodePoint
174/// [`Value::CharCluster`]: ../slvm/value/enum.Value.html#variant.CharCluster
175/// [`Value::CharClusterLong`]: ../slvm/value/enum.Value.html#variant.CharClusterLong
176/// Type to hold Slosh's notion of a char.
177///
178/// In slosh a character can either be an actual char, e.g. a [`Value::CodePoint`]
179/// or a [`Value::CharCluster`]/[`Value::CharClusterLong`] in which case it will
180/// be stored in an &str.
181#[derive(Debug, Clone, PartialEq, Eq)]
182pub enum SloshChar<'a> {
183 Char(char),
184 String(Cow<'a, str>),
185}
186
187impl Display for SloshChar<'_> {
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 let str = match self {
190 SloshChar::Char(c) => {
191 format!("{}", c)
192 }
193 SloshChar::String(c) => c.to_string(),
194 };
195 write!(f, "{}", str)
196 }
197}
198
199/// [`Value`]: ../slvm/value/enum.Value.html
200/// [`Value::Keyword`]: ../slvm/value/enum.Value.html#variant.Keyword
201/// Type to hold anything in Slosh that can be represented as a slosh Keyword: u32.
202///
203/// Public type used by rust native -> slosh bridge macro to represent
204/// arguments that reference a valid keyword.
205///
206/// Can represent SlRefInto [`Value`] types:
207/// - Keyword
208///
209/// Always returns a [`Value::Symbol`] type.
210pub struct Keyword(u32);
211
212impl From<u32> for Keyword {
213 fn from(value: u32) -> Self {
214 Self(value)
215 }
216}
217
218impl From<Keyword> for u32 {
219 fn from(value: Keyword) -> Self {
220 value.0
221 }
222}
223
224/// [`Value`]: ../slvm/value/enum.Value.html
225/// [`Value::Keyword`]: ../slvm/value/enum.Value.html#variant.Keyword
226/// Type to hold anything in Slosh that can be represented as a slosh symbol, however, this
227/// type, in contrast to [`Keyword`] does need to do some allocations, specifically when
228/// using [`SlFrom`]. Not a huge penalty but worth mentioning if unnecessary.
229///
230/// Public type used by rust native -> slosh bridge macro to represent
231/// arguments that reference a valid symbol.
232///
233/// Can represent SlRefInto [`Value`] types:
234/// - Keyword
235///
236/// Always returns a [`Value::Keyword`] type.
237pub struct KeywordAsString(String);
238
239impl AsRef<str> for KeywordAsString {
240 fn as_ref(&self) -> &str {
241 &self.0
242 }
243}
244
245impl From<String> for KeywordAsString {
246 fn from(value: String) -> Self {
247 Self(value)
248 }
249}
250
251impl From<KeywordAsString> for String {
252 fn from(value: KeywordAsString) -> Self {
253 value.0
254 }
255}
256
257/// Used by sl_sh_fn macro to embed information at runtime about the parameters of
258/// the rust native function, specifically whether it is a normal Type, or some
259/// supported wrapped type, e.g. Optional.
260#[derive(Copy, Clone, Debug, PartialEq, Eq)]
261pub enum TypeHandle {
262 Direct,
263 Optional,
264 VarArgs,
265}
266
267/// Used by sl_sh_fn macro to embed information at runtime about the parameters of
268/// the rust native function, specifically whether it is going to pass the value (a move),
269/// a reference, or mutable reference.
270#[derive(Copy, Clone, Debug, PartialEq, Eq)]
271pub enum PassingStyle {
272 Value,
273 Reference,
274 MutReference,
275}
276
277/// Struct used by sl_sh_fn macro to embed information in an array at runtime about each of
278/// the parameters of the rust native function.
279#[derive(Copy, Clone, Debug, PartialEq, Eq)]
280pub struct Param {
281 pub handle: TypeHandle,
282 pub passing_style: PassingStyle,
283}
284
285//TODO #224 use this but create a module there is a need for common error messages but there should be a consistent comprehensive approach.
286pub struct ErrorStrings {}
287
288impl ErrorStrings {
289 pub fn mismatched_type_context(
290 expected: impl AsRef<str>,
291 got: impl AsRef<str>,
292 context: impl AsRef<str>,
293 ) -> String {
294 if context.as_ref().is_empty() {
295 format!(
296 "mismatched type input, expected value of type {}, got {}.",
297 expected.as_ref(),
298 got.as_ref(),
299 )
300 } else {
301 format!(
302 "mismatched type input, expected value of type {}, got {}. {}",
303 expected.as_ref(),
304 got.as_ref(),
305 context.as_ref(),
306 )
307 }
308 }
309
310 pub fn mismatched_type(expected: impl AsRef<str>, got: impl AsRef<str>) -> String {
311 Self::mismatched_type_context(expected, got, "")
312 }
313
314 pub fn invalid_string(expected: impl AsRef<str>, got: impl AsRef<str>) -> String {
315 Self::mismatched_type_context(expected, got, "")
316 }
317
318 pub fn mismatched_type_with_context(
319 expected: impl AsRef<str>,
320 got: impl AsRef<str>,
321 additional: impl AsRef<str>,
322 ) -> String {
323 Self::mismatched_type_context(expected, got, additional)
324 }
325}