• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mattwparas / steel / 13615020054

02 Mar 2025 11:34AM UTC coverage: 47.089% (+0.03%) from 47.062%
13615020054

Pull #310

github

web-flow
Merge f80ed61d2 into f1a605a0f
Pull Request #310: support escaped identifiers

93 of 138 new or added lines in 4 files covered. (67.39%)

4 existing lines in 2 files now uncovered.

12737 of 27049 relevant lines covered (47.09%)

422185.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.44
/crates/steel-core/src/primitives.rs
1
pub mod bytevectors;
2
pub mod contracts;
3
mod control;
4
mod fs;
5
pub mod hashmaps;
6
pub mod hashsets;
7
pub mod http;
8
mod io;
9
pub mod lists;
10
pub mod meta_ops;
11
/// Implements numbers as defined in section 6.2 of the R7RS spec.
12
pub mod numbers;
13

14
#[cfg(not(target_arch = "wasm32"))]
15
pub mod polling;
16

17
pub mod ports;
18
pub mod process;
19
pub mod random;
20
mod streams;
21
pub mod strings;
22
mod symbols;
23
pub mod tcp;
24
pub mod time;
25
pub mod transducers;
26
mod utils;
27
pub mod vectors;
28

29
// This is for boot strapping the package
30
// manager with an embedded git implementation,
31
// as to not require depending on the system git.
32
pub mod git;
33

34
use crate::gc::{Gc, GcMut};
35
use crate::rvals::{FromSteelVal, IntoSteelVal, SteelByteVector};
36
use crate::rvals::{
37
    FunctionSignature, PrimitiveAsRef, PrimitiveAsRefMut, SteelHashMap, SteelHashSet, SteelVal,
38
    SteelVector,
39
};
40
use crate::values::closed::HeapRef;
41
use crate::values::lists::List;
42
use crate::values::port::SteelPort;
43
use crate::values::structs::UserDefinedStruct;
44
use crate::values::Vector;
45
use crate::{
46
    rerrs::{ErrorKind, SteelErr},
47
    rvals::SteelString,
48
};
49
pub use control::ControlOperations;
50
pub use fs::{fs_module, fs_module_sandbox};
51
pub use io::IoFunctions;
52
pub use lists::UnRecoverableResult;
53
pub use meta_ops::MetaOperations;
54
use num::{BigInt, BigRational, Rational32, ToPrimitive};
55
pub use numbers::{
56
    add_primitive, divide_primitive, multiply_primitive, subtract_primitive, NumOperations,
57
};
58
pub use ports::port_module;
59
use std::convert::TryFrom;
60
use std::result;
61
pub use streams::StreamOperations;
62
pub use strings::string_module;
63
pub use symbols::SymbolOperations;
64
pub use vectors::VectorOperations;
65

66
macro_rules! try_from_impl {
67
    ($type:ident => $($body:ty),*) => {
68
        $(
69
            impl TryFrom<SteelVal> for $body {
70
                type Error = SteelErr;
71
                #[inline]
72
                fn try_from(value: SteelVal) -> result::Result<Self, Self::Error> {
×
73
                    match value {
×
74
                        SteelVal::$type(x) => Ok(x.clone() as $body),
×
75
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
76
                    }
77
                }
78
            }
79

80
            impl TryFrom<&SteelVal> for $body {
81
                type Error = SteelErr;
82
                #[inline]
83
                fn try_from(value: &SteelVal) -> result::Result<Self, Self::Error> {
×
84
                    match value {
×
85
                        SteelVal::$type(x) => Ok(x.clone() as $body),
×
86
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
87
                    }
88
                }
89
            }
90

91
            impl FromSteelVal for $body {
92
                #[inline]
93
                fn from_steelval(value: &SteelVal) -> result::Result<Self, SteelErr> {
67,486✔
94
                    match value {
67,486✔
95
                        SteelVal::$type(x) => Ok(x.clone() as $body),
67,486✔
96
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
97
                    }
98
                }
99
            }
100

101
        )*
102
    };
103
}
104

105
macro_rules! from_f64 {
106
    ($($body:ty),*) => {
107
        $(
108
            impl From<$body> for SteelVal {
109
                #[inline]
110
                fn from(val: $body) -> SteelVal {
1✔
111
                    SteelVal::NumV(val as f64)
1✔
112
                }
113
            }
114

115
            impl IntoSteelVal for $body {
116
                #[inline]
117
                fn into_steelval(self) -> Result<SteelVal, SteelErr> {
296,304✔
118
                    Ok(SteelVal::NumV(self as f64))
296,304✔
119
                }
120
            }
121
        )*
122
    };
123
}
124

125
macro_rules! from_for_isize {
126
    ($($body:ty),*) => {
127
        $(
128
            impl From<$body> for SteelVal {
129
                #[inline]
130
                fn from(val: $body) -> SteelVal {
22✔
131
                    SteelVal::IntV(val as isize)
22✔
132
                }
133
            }
134

135
            impl IntoSteelVal for $body {
136
                #[inline]
137
                fn into_steelval(self) -> Result<SteelVal, SteelErr> {
6,608,202✔
138
                    Ok(SteelVal::IntV(self as isize))
6,608,202✔
139
                }
140
            }
141
        )*
142
    };
143
}
144

145
impl From<i64> for SteelVal {
146
    fn from(value: i64) -> Self {
×
147
        if let Ok(converted) = TryInto::<isize>::try_into(value) {
×
148
            SteelVal::IntV(converted)
149
        } else {
150
            SteelVal::BigNum(Gc::new(value.into()))
×
151
        }
152
    }
153
}
154

155
impl FromSteelVal for u8 {
156
    #[inline]
157
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
57✔
158
        match val {
57✔
159
            SteelVal::IntV(v) => (*v).try_into().map_err(|_err| {
57✔
160
                SteelErr::new(
×
161
                    ErrorKind::ConversionError,
×
162
                    format!("Unable to convert isize to u8: {}", v),
×
163
                )
164
            }),
165
            SteelVal::BigNum(n) => n.as_ref().try_into().map_err(|_err| {
×
166
                SteelErr::new(
×
167
                    ErrorKind::ConversionError,
×
168
                    format!("Unable to convert bignum to u8: {:?}", n),
×
169
                )
170
            }),
171
            _ => Err(SteelErr::new(
×
172
                ErrorKind::ConversionError,
×
173
                format!("Unable to convert steelval to u8: {}", val),
×
174
            )),
175
        }
176
    }
177
}
178

179
impl From<usize> for SteelVal {
180
    #[inline]
181
    fn from(value: usize) -> Self {
5,966✔
182
        if value > isize::MAX as usize {
5,966✔
183
            SteelVal::BigNum(Gc::new(value.into()))
×
184
        } else {
185
            SteelVal::IntV(value as isize)
5,966✔
186
        }
187
    }
188
}
189

190
impl IntoSteelVal for usize {
191
    #[inline]
192
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
5,966✔
193
        Ok(SteelVal::from(self))
5,966✔
194
    }
195
}
196

197
impl IntoSteelVal for i64 {
198
    #[inline]
199
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
×
200
        Ok(self.into())
×
201
    }
202
}
203

204
impl FromSteelVal for i64 {
205
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
×
206
        match val {
×
207
            SteelVal::IntV(v) => (*v).try_into().map_err(|_err| {
×
208
                SteelErr::new(
×
209
                    ErrorKind::ConversionError,
×
210
                    format!("Unable to convert i64 to isize: {}", v),
×
211
                )
212
            }),
213
            SteelVal::BigNum(n) => n.as_ref().try_into().map_err(|_err| {
×
214
                SteelErr::new(
×
215
                    ErrorKind::ConversionError,
×
216
                    format!("Unable to convert bignum to isize: {:?}", n),
×
217
                )
218
            }),
219
            _ => Err(SteelErr::new(
×
220
                ErrorKind::ConversionError,
×
221
                format!("Unable to convert steelval to isize: {}", val),
×
222
            )),
223
        }
224
    }
225
}
226

227
impl From<char> for SteelVal {
228
    #[inline]
229
    fn from(val: char) -> SteelVal {
×
230
        SteelVal::CharV(val)
×
231
    }
232
}
233

234
impl IntoSteelVal for char {
235
    #[inline]
236
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
417✔
237
        Ok(SteelVal::CharV(self))
417✔
238
    }
239
}
240

241
impl FromSteelVal for char {
242
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
3,505✔
243
        if let SteelVal::CharV(c) = val {
7,010✔
244
            Ok(*c)
245
        } else {
246
            Err(SteelErr::new(
×
247
                ErrorKind::ConversionError,
×
248
                "Expected character".to_string(),
×
249
            ))
250
        }
251
    }
252
}
253

254
impl<T: Into<SteelVal>> From<Option<T>> for SteelVal {
255
    #[inline]
256
    fn from(val: Option<T>) -> SteelVal {
×
257
        if let Some(s) = val {
×
258
            s.into()
×
259
        } else {
260
            SteelVal::BoolV(true)
×
261
        }
262
    }
263
}
264

265
impl<T: IntoSteelVal> IntoSteelVal for Option<T> {
266
    #[inline]
267
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
1,774✔
268
        if let Some(s) = self {
3,471✔
269
            s.into_steelval()
×
270
        } else {
271
            Ok(SteelVal::BoolV(false))
77✔
272
        }
273
    }
274
}
275

276
impl<T: FromSteelVal> FromSteelVal for Option<T> {
277
    #[inline]
278
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
3,271✔
279
        if val.is_truthy() {
3,271✔
280
            Ok(Some(T::from_steelval(val)?))
2,258✔
281
        } else {
282
            Ok(None)
1,013✔
283
        }
284
    }
285
}
286

287
impl FromSteelVal for SteelVal {
288
    #[inline]
289
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
1,265,175✔
290
        Ok(val.clone())
1,265,175✔
291
    }
292
}
293

294
impl FromSteelVal for () {
295
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
×
296
        if let SteelVal::Void = val {
×
297
            Ok(())
×
298
        } else {
299
            crate::stop!(ConversionError => "could not convert value to unit type")
×
300
        }
301
    }
302
}
303

304
impl IntoSteelVal for () {
305
    #[inline]
306
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
×
307
        Ok(SteelVal::Void)
×
308
    }
309
}
310

311
impl From<()> for SteelVal {
312
    #[inline]
313
    fn from(_: ()) -> SteelVal {
×
314
        SteelVal::Void
×
315
    }
316
}
317

318
impl IntoSteelVal for Rational32 {
319
    #[inline]
320
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
14✔
321
        if self.is_integer() {
14✔
322
            self.numer().into_steelval()
2✔
323
        } else {
324
            Ok(SteelVal::Rational(self))
12✔
325
        }
326
    }
327
}
328

329
impl IntoSteelVal for BigInt {
330
    #[inline]
331
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
6✔
332
        match self.to_isize() {
6✔
333
            Some(i) => i.into_steelval(),
×
334
            None => Ok(SteelVal::BigNum(crate::gc::Gc::new(self))),
6✔
335
        }
336
    }
337
}
338

339
impl IntoSteelVal for BigRational {
340
    #[inline]
341
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
×
342
        if self.is_integer() {
×
343
            let (n, _) = self.into();
×
344
            return n.into_steelval();
×
345
        }
346
        match (self.numer().to_i32(), self.denom().to_i32()) {
×
347
            (Some(n), Some(d)) => Rational32::new(n, d).into_steelval(),
×
348
            _ => Ok(SteelVal::BigRational(Gc::new(self))),
×
349
        }
350
    }
351
}
352

353
from_f64!(f64, f32);
354
from_for_isize!(i32, i16, i8, u8, u16, u32, u64, isize);
355
try_from_impl!(NumV => f64, f32);
356
try_from_impl!(IntV => i32, i16, i8, u16, u32, u64, usize, isize);
357

358
impl TryFrom<SteelVal> for String {
359
    type Error = SteelErr;
360
    #[inline]
UNCOV
361
    fn try_from(value: SteelVal) -> result::Result<Self, Self::Error> {
×
UNCOV
362
        match value {
×
UNCOV
363
            SteelVal::StringV(ref x) => Ok(x.to_string()),
×
364
            SteelVal::SymbolV(ref x) => Ok(x.to_string()),
×
365
            _ => Err(SteelErr::new(
×
366
                ErrorKind::ConversionError,
×
367
                "Expected string".to_string(),
×
368
            )),
369
        }
370
    }
371
}
372

373
impl From<SteelVal> for Gc<SteelVal> {
374
    #[inline]
375
    fn from(val: SteelVal) -> Self {
×
376
        Gc::new(val)
×
377
    }
378
}
379

380
impl From<Gc<SteelVal>> for SteelVal {
381
    #[inline]
382
    fn from(val: Gc<SteelVal>) -> Self {
11✔
383
        (*val).clone()
11✔
384
    }
385
}
386

387
impl FromSteelVal for String {
388
    #[inline]
389
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
10,883✔
390
        match val {
10,883✔
391
            SteelVal::StringV(s) | SteelVal::SymbolV(s) => Ok(s.to_string()),
21,766✔
392
            _ => Err(SteelErr::new(
×
393
                ErrorKind::ConversionError,
×
394
                format!("Expected string, found: {val}"),
×
395
            )),
396
        }
397
    }
398
}
399

400
impl TryFrom<&SteelVal> for String {
401
    type Error = SteelErr;
402
    #[inline]
403
    fn try_from(value: &SteelVal) -> result::Result<Self, Self::Error> {
1✔
404
        match value {
1✔
405
            SteelVal::StringV(x) => Ok(x.to_string()),
1✔
406
            SteelVal::SymbolV(x) => Ok(x.to_string()),
×
407
            _ => Err(SteelErr::new(
×
408
                ErrorKind::ConversionError,
×
409
                "Expected string".to_string(),
×
410
            )),
411
        }
412
    }
413
}
414

415
impl From<String> for SteelVal {
416
    #[inline]
417
    fn from(val: String) -> SteelVal {
×
418
        SteelVal::StringV(val.into())
×
419
    }
420
}
421

422
impl IntoSteelVal for &str {
423
    #[inline]
424
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
×
425
        Ok(SteelVal::StringV(self.into()))
×
426
    }
427
}
428

429
impl FromSteelVal for SteelString {
430
    #[inline]
431
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
6✔
432
        if let SteelVal::StringV(s) = val {
12✔
433
            Ok(s.clone())
×
434
        } else {
435
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel string", val))
×
436
        }
437
    }
438
}
439

440
pub enum Either<L, R> {
441
    Left(L),
442
    Right(R),
443
}
444

445
impl<'a, L: PrimitiveAsRef<'a>, R: PrimitiveAsRef<'a>> PrimitiveAsRef<'a> for Either<L, R> {
446
    #[inline(always)]
447
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
31✔
448
        let left_type_name = std::any::type_name::<L>();
31✔
449
        let right_type_name = std::any::type_name::<R>();
31✔
450

451
        let error_thunk = crate::throw!(ConversionError => format!("Cannot convert steel value to the specified type: {} or {}", left_type_name, right_type_name));
31✔
452

453
        Self::maybe_primitive_as_ref(val).ok_or_else(error_thunk)
31✔
454
    }
455

456
    #[inline(always)]
457
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
31✔
458
        L::maybe_primitive_as_ref(val)
31✔
459
            .map(Either::Left)
31✔
460
            .or_else(|| R::maybe_primitive_as_ref(val).map(Either::Right))
77✔
461
    }
462
}
463

464
impl<'a> PrimitiveAsRef<'a> for &'a SteelByteVector {
465
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
33✔
466
        Self::maybe_primitive_as_ref(val).ok_or_else(
33✔
467
            crate::throw!(ConversionError => format!("Cannot convert value to bytevector: {}", val)),
33✔
468
        )
469
    }
470

471
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
33✔
472
        if let SteelVal::ByteVector(s) = val {
66✔
473
            Some(s)
×
474
        } else {
475
            None
×
476
        }
477
    }
478
}
479

480
impl<'a> PrimitiveAsRef<'a> for &'a UserDefinedStruct {
481
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
482
        Self::maybe_primitive_as_ref(val).ok_or_else(
×
483
            crate::throw!(ConversionError => format!("Cannot convert value to struct: {}", val)),
×
484
        )
485
    }
486

487
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
488
        if let SteelVal::CustomStruct(s) = val {
×
489
            Some(s)
×
490
        } else {
491
            None
×
492
        }
493
    }
494
}
495

496
impl<'a> PrimitiveAsRef<'a> for &'a GcMut<SteelVal> {
497
    #[inline(always)]
498
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
499
        if let SteelVal::Boxed(c) = val {
×
500
            Ok(c)
×
501
        } else {
502
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel boxed value", val))
×
503
        }
504
    }
505

506
    #[inline(always)]
507
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
508
        if let SteelVal::Boxed(c) = val {
×
509
            Some(c)
×
510
        } else {
511
            None
×
512
        }
513
    }
514
}
515

516
impl<'a> PrimitiveAsRef<'a> for &'a HeapRef<SteelVal> {
517
    #[inline(always)]
518
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
6,934,460✔
519
        if let SteelVal::HeapAllocated(b) = val {
13,868,920✔
520
            Ok(b)
×
521
        } else {
522
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel box", val))
×
523
        }
524
    }
525

526
    #[inline(always)]
527
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
528
        if let SteelVal::HeapAllocated(b) = val {
×
529
            Some(b)
×
530
        } else {
531
            None
×
532
        }
533
    }
534
}
535

536
impl<'a> PrimitiveAsRef<'a> for &'a char {
537
    #[inline(always)]
538
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
398✔
539
        if let SteelVal::CharV(c) = val {
796✔
540
            Ok(c)
×
541
        } else {
542
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel character", val))
×
543
        }
544
    }
545

546
    #[inline(always)]
547
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
548
        if let SteelVal::CharV(c) = val {
×
549
            Some(c)
×
550
        } else {
551
            None
×
552
        }
553
    }
554
}
555

556
impl<'a> PrimitiveAsRef<'a> for char {
557
    #[inline(always)]
558
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
15,720✔
559
        if let SteelVal::CharV(c) = val {
31,440✔
560
            Ok(*c)
×
561
        } else {
562
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel character", val))
×
563
        }
564
    }
565

566
    #[inline(always)]
567
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
568
        if let SteelVal::CharV(c) = val {
×
569
            Some(*c)
×
570
        } else {
571
            None
×
572
        }
573
    }
574
}
575

576
impl<'a> PrimitiveAsRef<'a> for isize {
577
    #[inline(always)]
578
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
87✔
579
        if let SteelVal::IntV(i) = val {
174✔
580
            Ok(*i)
×
581
        } else {
582
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel int", val))
×
583
        }
584
    }
585

586
    #[inline(always)]
587
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
588
        if let SteelVal::IntV(i) = val {
×
589
            Some(*i)
×
590
        } else {
591
            None
×
592
        }
593
    }
594
}
595

596
impl<'a> PrimitiveAsRef<'a> for &'a Gc<Vector<SteelVal>> {
597
    #[inline(always)]
598
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
599
        if let SteelVal::VectorV(p) = val {
×
600
            Ok(&p.0)
×
601
        } else {
602
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel vector", val))
×
603
        }
604
    }
605

606
    #[inline(always)]
607
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
608
        if let SteelVal::VectorV(p) = val {
×
609
            Some(&p.0)
×
610
        } else {
611
            None
×
612
        }
613
    }
614
}
615

616
impl<'a> PrimitiveAsRef<'a> for &'a SteelVector {
617
    #[inline(always)]
618
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
8✔
619
        if let SteelVal::VectorV(p) = val {
16✔
620
            Ok(p)
×
621
        } else {
622
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel vector", val))
×
623
        }
624
    }
625

626
    #[inline(always)]
627
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
27✔
628
        if let SteelVal::VectorV(p) = val {
49✔
629
            Some(p)
×
630
        } else {
631
            None
5✔
632
        }
633
    }
634
}
635

636
impl<'a> PrimitiveAsRef<'a> for &'a Gc<crate::values::HashSet<SteelVal>> {
637
    #[inline(always)]
638
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
639
        if let SteelVal::HashSetV(p) = val {
×
640
            Ok(&p.0)
×
641
        } else {
642
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel hashset", val))
×
643
        }
644
    }
645

646
    #[inline(always)]
647
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
648
        if let SteelVal::HashSetV(p) = val {
×
649
            Some(&p.0)
×
650
        } else {
651
            None
×
652
        }
653
    }
654
}
655

656
impl<'a> PrimitiveAsRef<'a> for &'a SteelHashSet {
657
    #[inline(always)]
658
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
55✔
659
        if let SteelVal::HashSetV(p) = val {
110✔
660
            Ok(p)
×
661
        } else {
662
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel hashset", val))
×
663
        }
664
    }
665

666
    #[inline(always)]
667
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
668
        if let SteelVal::HashSetV(p) = val {
×
669
            Some(p)
×
670
        } else {
671
            None
×
672
        }
673
    }
674
}
675

676
impl<'a> PrimitiveAsRef<'a> for &'a HeapRef<Vec<SteelVal>> {
677
    #[inline(always)]
678
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
1,267,576✔
679
        if let SteelVal::MutableVector(p) = val {
2,535,152✔
680
            Ok(p)
×
681
        } else {
682
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel mutable vector", val))
×
683
        }
684
    }
685

686
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
19✔
687
        if let SteelVal::MutableVector(p) = val {
28✔
688
            Some(p)
×
689
        } else {
690
            None
10✔
691
        }
692
    }
693
}
694

695
impl<'a> PrimitiveAsRef<'a> for &'a SteelPort {
696
    #[inline(always)]
697
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
16,593✔
698
        if let SteelVal::PortV(p) = val {
33,186✔
699
            Ok(p)
×
700
        } else {
701
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel port", val))
×
702
        }
703
    }
704

705
    #[inline(always)]
706
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
707
        if let SteelVal::PortV(p) = val {
×
708
            Some(p)
×
709
        } else {
710
            None
×
711
        }
712
    }
713
}
714

715
impl<'a> PrimitiveAsRef<'a> for &'a List<SteelVal> {
716
    #[inline(always)]
717
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
93,970✔
718
        if let SteelVal::ListV(l) = val {
187,938✔
719
            Ok(l)
×
720
        } else {
721
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel list", val))
2✔
722
        }
723
    }
724

725
    #[inline(always)]
726
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
727
        if let SteelVal::ListV(l) = val {
×
728
            Some(l)
×
729
        } else {
730
            None
×
731
        }
732
    }
733
}
734

735
impl<'a> PrimitiveAsRef<'a> for &'a SteelVal {
736
    #[inline(always)]
737
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
104,915✔
738
        Ok(val)
104,915✔
739
    }
740

741
    #[inline(always)]
742
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
743
        Some(val)
×
744
    }
745
}
746

747
impl<'a> PrimitiveAsRefMut<'a> for &'a mut SteelVal {
748
    #[inline(always)]
749
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
435,695✔
750
        Ok(val)
435,695✔
751
    }
752

753
    #[inline(always)]
754
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
755
        Some(val)
×
756
    }
757
}
758

759
impl<'a> PrimitiveAsRef<'a> for &'a SteelString {
760
    #[inline(always)]
761
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
50,948✔
762
        if let SteelVal::StringV(s) = val {
101,886✔
763
            Ok(s)
×
764
        } else {
765
            crate::stop!(TypeMismatch => format!("Cannot convert steel value: {} to steel string", val))
10✔
766
        }
767
    }
768

769
    #[inline(always)]
770
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
771
        if let SteelVal::StringV(s) = val {
×
772
            Some(s)
×
773
        } else {
774
            None
×
775
        }
776
    }
777
}
778

779
impl<'a> PrimitiveAsRef<'a> for &'a Gc<crate::values::HashMap<SteelVal, SteelVal>> {
780
    #[inline(always)]
781
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
17,691✔
782
        if let SteelVal::HashMapV(hm) = val {
35,382✔
783
            Ok(&hm.0)
×
784
        } else {
785
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
786
        }
787
    }
788

789
    #[inline(always)]
790
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
791
        if let SteelVal::HashMapV(hm) = val {
×
792
            Some(&hm.0)
×
793
        } else {
794
            None
×
795
        }
796
    }
797
}
798

799
impl<'a> PrimitiveAsRefMut<'a> for &'a mut Gc<crate::values::HashMap<SteelVal, SteelVal>> {
800
    #[inline(always)]
801
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
×
802
        if let SteelVal::HashMapV(hm) = val {
×
803
            Ok(&mut hm.0)
×
804
        } else {
805
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
806
        }
807
    }
808

809
    #[inline(always)]
810
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
811
        if let SteelVal::HashMapV(hm) = val {
×
812
            Some(&mut hm.0)
×
813
        } else {
814
            None
×
815
        }
816
    }
817
}
818

819
impl<'a> PrimitiveAsRefMut<'a> for &'a mut SteelByteVector {
820
    #[inline(always)]
821
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
1✔
822
        if let SteelVal::ByteVector(hm) = val {
2✔
823
            Ok(hm)
×
824
        } else {
825
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to bytevector", val))
×
826
        }
827
    }
828

829
    #[inline(always)]
830
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
831
        if let SteelVal::ByteVector(hm) = val {
×
832
            Some(hm)
×
833
        } else {
834
            None
×
835
        }
836
    }
837
}
838

839
impl<'a> PrimitiveAsRef<'a> for &'a SteelHashMap {
840
    #[inline(always)]
841
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
842
        if let SteelVal::HashMapV(hm) = val {
×
843
            Ok(hm)
×
844
        } else {
845
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
846
        }
847
    }
848

849
    #[inline(always)]
850
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
851
        if let SteelVal::HashMapV(hm) = val {
×
852
            Some(hm)
×
853
        } else {
854
            None
×
855
        }
856
    }
857
}
858

859
impl IntoSteelVal for String {
860
    #[inline(always)]
861
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
1✔
862
        Ok(SteelVal::StringV(self.into()))
1✔
863
    }
864
}
865

866
impl IntoSteelVal for SteelString {
867
    #[inline(always)]
868
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
×
869
        Ok(SteelVal::StringV(self))
×
870
    }
871
}
872

873
impl From<String> for Gc<SteelVal> {
874
    #[inline(always)]
875
    fn from(val: String) -> Gc<SteelVal> {
×
876
        Gc::new(val.into())
×
877
    }
878
}
879

880
impl From<bool> for SteelVal {
881
    #[inline(always)]
882
    fn from(val: bool) -> SteelVal {
14,057✔
883
        SteelVal::BoolV(val)
14,057✔
884
    }
885
}
886

887
impl FromSteelVal for bool {
888
    #[inline(always)]
889
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<bool> {
700✔
890
        if let SteelVal::BoolV(b) = val {
1,400✔
891
            Ok(*b)
×
892
        } else {
893
            crate::stop!(ConversionError => format!("Cannot convert steel value: {val} to boolean"))
×
894
        }
895
    }
896
}
897

898
impl IntoSteelVal for bool {
899
    #[inline(always)]
900
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
1,943✔
901
        Ok(SteelVal::BoolV(self))
1,943✔
902
    }
903
}
904

905
impl From<Vector<SteelVal>> for SteelVal {
906
    #[inline(always)]
907
    fn from(val: Vector<SteelVal>) -> SteelVal {
×
908
        SteelVal::VectorV(Gc::new(val).into())
×
909
    }
910
}
911

912
impl From<FunctionSignature> for SteelVal {
913
    fn from(val: FunctionSignature) -> SteelVal {
×
914
        SteelVal::FuncV(val)
×
915
    }
916
}
917

918
#[cfg(test)]
919
mod try_from_tests {
920

921
    use super::*;
922

923
    #[test]
924
    fn from_char() {
925
        assert_eq!(SteelVal::from('c'), SteelVal::CharV('c'));
926
    }
927

928
    #[test]
929
    fn from_steelval_char() {
930
        assert_eq!(char::from_steelval(&SteelVal::CharV('c')).unwrap(), 'c')
931
    }
932

933
    #[test]
934
    fn into_steelval_char() {
935
        assert_eq!('c'.into_steelval().unwrap(), SteelVal::CharV('c'))
936
    }
937

938
    #[test]
939
    fn from_steelval_usize() {
940
        assert_eq!(usize::from_steelval(&SteelVal::IntV(10)).unwrap(), 10)
941
    }
942

943
    #[test]
944
    fn from_steelval_i32() {
945
        assert_eq!(i32::from_steelval(&SteelVal::IntV(32)).unwrap(), 32)
946
    }
947

948
    #[test]
949
    fn into_steelval_i32() {
950
        assert_eq!(32.into_steelval().unwrap(), SteelVal::IntV(32))
951
    }
952

953
    #[test]
954
    fn from_bool() {
955
        assert_eq!(SteelVal::from(true), SteelVal::BoolV(true));
956
    }
957

958
    #[test]
959
    fn try_from_steelval_string() {
960
        let expected = "foo".to_string();
961
        let input = SteelVal::StringV("foo".into());
962

963
        let res = String::try_from(input);
964
        assert_eq!(res.unwrap(), expected);
965
    }
966

967
    #[test]
968
    fn try_from_steelval_ref_string() {
969
        let expected = "foo".to_string();
970
        let input = SteelVal::StringV("foo".into());
971

972
        let res = String::try_from(&input);
973
        assert_eq!(res.unwrap(), expected);
974
    }
975
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc