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

mattwparas / steel / 11924200389

20 Nov 2024 12:20AM UTC coverage: 46.725% (-0.2%) from 46.956%
11924200389

Pull #290

github

web-flow
Merge faebbd075 into a6f7286de
Pull Request #290: Fix provides within macros

37 of 263 new or added lines in 7 files covered. (14.07%)

27 existing lines in 11 files now uncovered.

12469 of 26686 relevant lines covered (46.72%)

483326.6 hits per line

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

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

61
macro_rules! try_from_impl {
62
    ($type:ident => $($body:ty),*) => {
63
        $(
64
            impl TryFrom<SteelVal> for $body {
65
                type Error = SteelErr;
66
                fn try_from(value: SteelVal) -> result::Result<Self, Self::Error> {
×
67
                    match value {
×
68
                        SteelVal::$type(x) => Ok(x.clone() as $body),
×
69
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
70
                    }
71
                }
72
            }
73

74
            impl TryFrom<&SteelVal> for $body {
75
                type Error = SteelErr;
76
                fn try_from(value: &SteelVal) -> result::Result<Self, Self::Error> {
×
77
                    match value {
×
78
                        SteelVal::$type(x) => Ok(x.clone() as $body),
×
79
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
80
                    }
81
                }
82
            }
83

84
            impl FromSteelVal for $body {
85
                fn from_steelval(value: &SteelVal) -> result::Result<Self, SteelErr> {
2,492,340✔
86
                    match value {
2,492,340✔
87
                        SteelVal::$type(x) => Ok(x.clone() as $body),
2,492,340✔
88
                        _ => Err(SteelErr::new(ErrorKind::ConversionError, format!("Expected number, found: {}", value))),
×
89
                    }
90
                }
91
            }
92

93
        )*
94
    };
95
}
96

97
macro_rules! from_f64 {
98
    ($($body:ty),*) => {
99
        $(
100
            impl From<$body> for SteelVal {
101
                fn from(val: $body) -> SteelVal {
1✔
102
                    SteelVal::NumV(val as f64)
1✔
103
                }
104
            }
105

106
            impl IntoSteelVal for $body {
107
                fn into_steelval(self) -> Result<SteelVal, SteelErr> {
994✔
108
                    Ok(SteelVal::NumV(self as f64))
994✔
109
                }
110
            }
111
        )*
112
    };
113
}
114

115
macro_rules! from_for_isize {
116
    ($($body:ty),*) => {
117
        $(
118
            impl From<$body> for SteelVal {
119
                fn from(val: $body) -> SteelVal {
22✔
120
                    SteelVal::IntV(val as isize)
22✔
121
                }
122
            }
123

124
            impl IntoSteelVal for $body {
125
                fn into_steelval(self) -> Result<SteelVal, SteelErr> {
72,627✔
126
                    Ok(SteelVal::IntV(self as isize))
72,627✔
127
                }
128
            }
129
        )*
130
    };
131
}
132

133
impl From<i64> for SteelVal {
134
    fn from(value: i64) -> Self {
×
135
        if let Ok(converted) = TryInto::<isize>::try_into(value) {
×
136
            SteelVal::IntV(converted)
137
        } else {
138
            SteelVal::BigNum(Gc::new(value.into()))
×
139
        }
140
    }
141
}
142

143
impl FromSteelVal for u8 {
144
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
57✔
145
        match val {
57✔
146
            SteelVal::IntV(v) => (*v).try_into().map_err(|_err| {
57✔
147
                SteelErr::new(
×
148
                    ErrorKind::ConversionError,
×
149
                    format!("Unable to convert isize to u8: {}", v),
×
150
                )
151
            }),
152
            SteelVal::BigNum(n) => n.as_ref().try_into().map_err(|_err| {
×
153
                SteelErr::new(
×
154
                    ErrorKind::ConversionError,
×
155
                    format!("Unable to convert bignum to u8: {:?}", n),
×
156
                )
157
            }),
158
            _ => Err(SteelErr::new(
×
159
                ErrorKind::ConversionError,
×
160
                format!("Unable to convert steelval to u8: {}", val),
×
161
            )),
162
        }
163
    }
164
}
165

166
impl From<usize> for SteelVal {
167
    fn from(value: usize) -> Self {
73,517✔
168
        if value > isize::MAX as usize {
73,517✔
169
            SteelVal::BigNum(Gc::new(value.into()))
×
170
        } else {
171
            SteelVal::IntV(value as isize)
73,517✔
172
        }
173
    }
174
}
175

176
impl IntoSteelVal for usize {
177
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
73,517✔
178
        Ok(SteelVal::from(self))
73,517✔
179
    }
180
}
181

182
impl IntoSteelVal for i64 {
183
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
×
184
        Ok(self.into())
×
185
    }
186
}
187

188
impl FromSteelVal for i64 {
189
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
×
190
        match val {
×
191
            SteelVal::IntV(v) => (*v).try_into().map_err(|_err| {
×
192
                SteelErr::new(
×
193
                    ErrorKind::ConversionError,
×
194
                    format!("Unable to convert i64 to isize: {}", v),
×
195
                )
196
            }),
197
            SteelVal::BigNum(n) => n.as_ref().try_into().map_err(|_err| {
×
198
                SteelErr::new(
×
199
                    ErrorKind::ConversionError,
×
200
                    format!("Unable to convert bignum to isize: {:?}", n),
×
201
                )
202
            }),
203
            _ => Err(SteelErr::new(
×
204
                ErrorKind::ConversionError,
×
205
                format!("Unable to convert steelval to isize: {}", val),
×
206
            )),
207
        }
208
    }
209
}
210

211
impl From<char> for SteelVal {
212
    fn from(val: char) -> SteelVal {
1✔
213
        SteelVal::CharV(val)
1✔
214
    }
215
}
216

217
impl IntoSteelVal for char {
218
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
1✔
219
        Ok(SteelVal::CharV(self))
1✔
220
    }
221
}
222

223
impl FromSteelVal for char {
224
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
3,459✔
225
        if let SteelVal::CharV(c) = val {
6,918✔
226
            Ok(*c)
227
        } else {
228
            Err(SteelErr::new(
×
229
                ErrorKind::ConversionError,
×
230
                "Expected character".to_string(),
×
231
            ))
232
        }
233
    }
234
}
235

236
impl<T: Into<SteelVal>> From<Option<T>> for SteelVal {
237
    fn from(val: Option<T>) -> SteelVal {
×
238
        if let Some(s) = val {
×
239
            s.into()
×
240
        } else {
241
            SteelVal::BoolV(true)
×
242
        }
243
    }
244
}
245

246
impl<T: IntoSteelVal> IntoSteelVal for Option<T> {
247
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
2,430✔
248
        if let Some(s) = self {
4,468✔
249
            s.into_steelval()
×
250
        } else {
251
            Ok(SteelVal::BoolV(false))
392✔
252
        }
253
    }
254
}
255

256
impl<T: FromSteelVal> FromSteelVal for Option<T> {
257
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
3,124✔
258
        if val.is_truthy() {
3,124✔
259
            Ok(Some(T::from_steelval(val)?))
2,125✔
260
        } else {
261
            Ok(None)
999✔
262
        }
263
    }
264
}
265

266
impl FromSteelVal for SteelVal {
267
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
3,491,392✔
268
        Ok(val.clone())
3,491,392✔
269
    }
270
}
271

272
impl FromSteelVal for () {
273
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
×
274
        if let SteelVal::Void = val {
×
275
            Ok(())
×
276
        } else {
277
            crate::stop!(ConversionError => "could not convert value to unit type")
×
278
        }
279
    }
280
}
281

282
impl IntoSteelVal for () {
283
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
1,889✔
284
        Ok(SteelVal::Void)
1,889✔
285
    }
286
}
287

288
impl From<()> for SteelVal {
289
    fn from(_: ()) -> SteelVal {
×
290
        SteelVal::Void
×
291
    }
292
}
293

294
impl IntoSteelVal for Rational32 {
295
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
18✔
296
        if self.is_integer() {
18✔
297
            self.numer().into_steelval()
2✔
298
        } else {
299
            Ok(SteelVal::Rational(self))
16✔
300
        }
301
    }
302
}
303

304
impl IntoSteelVal for BigInt {
305
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
301✔
306
        match self.to_isize() {
301✔
307
            Some(i) => i.into_steelval(),
2✔
308
            None => Ok(SteelVal::BigNum(crate::gc::Gc::new(self))),
299✔
309
        }
310
    }
311
}
312

313
impl IntoSteelVal for BigRational {
314
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
50✔
315
        if self.is_integer() {
50✔
316
            let (n, _) = self.into();
1✔
317
            return n.into_steelval();
1✔
318
        }
319
        match (self.numer().to_i32(), self.denom().to_i32()) {
49✔
320
            (Some(n), Some(d)) => Rational32::new(n, d).into_steelval(),
3✔
321
            _ => Ok(SteelVal::BigRational(Gc::new(self))),
46✔
322
        }
323
    }
324
}
325

326
from_f64!(f64, f32);
327
from_for_isize!(i32, i16, i8, u8, u16, u32, u64, isize);
328
try_from_impl!(NumV => f64, f32);
329
try_from_impl!(IntV => i32, i16, i8, u16, u32, u64, usize, isize);
330

331
impl TryFrom<SteelVal> for String {
332
    type Error = SteelErr;
333
    fn try_from(value: SteelVal) -> result::Result<Self, Self::Error> {
1✔
334
        match value {
1✔
335
            SteelVal::StringV(ref x) => Ok(x.to_string()),
1✔
336
            SteelVal::SymbolV(ref x) => Ok(x.to_string()),
×
337
            _ => Err(SteelErr::new(
×
338
                ErrorKind::ConversionError,
×
339
                "Expected string".to_string(),
×
340
            )),
341
        }
342
    }
343
}
344

345
impl From<SteelVal> for Gc<SteelVal> {
346
    fn from(val: SteelVal) -> Self {
×
347
        Gc::new(val)
×
348
    }
349
}
350

351
impl From<Gc<SteelVal>> for SteelVal {
352
    fn from(val: Gc<SteelVal>) -> Self {
11✔
353
        (*val).clone()
11✔
354
    }
355
}
356

357
impl FromSteelVal for String {
358
    fn from_steelval(val: &SteelVal) -> Result<Self, SteelErr> {
9,360✔
359
        match val {
9,360✔
360
            SteelVal::StringV(s) | SteelVal::SymbolV(s) => Ok(s.to_string()),
18,720✔
361
            _ => Err(SteelErr::new(
×
362
                ErrorKind::ConversionError,
×
363
                format!("Expected string, found: {val}"),
×
364
            )),
365
        }
366
    }
367
}
368

369
impl TryFrom<&SteelVal> for String {
370
    type Error = SteelErr;
371
    fn try_from(value: &SteelVal) -> result::Result<Self, Self::Error> {
1✔
372
        match value {
1✔
373
            SteelVal::StringV(x) => Ok(x.to_string()),
1✔
374
            SteelVal::SymbolV(x) => Ok(x.to_string()),
×
375
            _ => Err(SteelErr::new(
×
376
                ErrorKind::ConversionError,
×
377
                "Expected string".to_string(),
×
378
            )),
379
        }
380
    }
381
}
382

383
impl From<String> for SteelVal {
384
    fn from(val: String) -> SteelVal {
2,132✔
385
        SteelVal::StringV(val.into())
2,132✔
386
    }
387
}
388

389
impl IntoSteelVal for &str {
390
    #[inline(always)]
391
    fn into_steelval(self) -> crate::rvals::Result<SteelVal> {
×
392
        Ok(SteelVal::StringV(self.into()))
×
393
    }
394
}
395

396
impl FromSteelVal for SteelString {
397
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<Self> {
699✔
398
        if let SteelVal::StringV(s) = val {
1,398✔
399
            Ok(s.clone())
400
        } else {
401
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel string", val))
×
402
        }
403
    }
404
}
405

406
pub enum Either<L, R> {
407
    Left(L),
408
    Right(R),
409
}
410

411
impl<'a, L: PrimitiveAsRef<'a>, R: PrimitiveAsRef<'a>> PrimitiveAsRef<'a> for Either<L, R> {
412
    #[inline(always)]
413
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
31✔
414
        let left_type_name = std::any::type_name::<L>();
31✔
415
        let right_type_name = std::any::type_name::<R>();
31✔
416

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

419
        Self::maybe_primitive_as_ref(val).ok_or_else(error_thunk)
31✔
420
    }
421

422
    #[inline(always)]
423
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
31✔
424
        L::maybe_primitive_as_ref(val)
31✔
425
            .map(Either::Left)
31✔
426
            .or_else(|| R::maybe_primitive_as_ref(val).map(Either::Right))
77✔
427
    }
428
}
429

430
impl<'a> PrimitiveAsRef<'a> for &'a SteelByteVector {
431
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
33✔
432
        Self::maybe_primitive_as_ref(val).ok_or_else(
33✔
433
            crate::throw!(ConversionError => format!("Cannot convert value to bytevector: {}", val)),
33✔
434
        )
435
    }
436

437
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
33✔
438
        if let SteelVal::ByteVector(s) = val {
66✔
439
            Some(s)
×
440
        } else {
441
            None
×
442
        }
443
    }
444
}
445

446
impl<'a> PrimitiveAsRef<'a> for &'a UserDefinedStruct {
447
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
448
        Self::maybe_primitive_as_ref(val).ok_or_else(
×
449
            crate::throw!(ConversionError => format!("Cannot convert value to struct: {}", val)),
×
450
        )
451
    }
452

453
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
454
        if let SteelVal::CustomStruct(s) = val {
×
455
            Some(s)
×
456
        } else {
457
            None
×
458
        }
459
    }
460
}
461

462
impl<'a> PrimitiveAsRef<'a> for &'a GcMut<SteelVal> {
463
    #[inline(always)]
464
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
465
        if let SteelVal::Boxed(c) = val {
×
466
            Ok(c)
×
467
        } else {
468
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel boxed value", val))
×
469
        }
470
    }
471

472
    #[inline(always)]
473
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
474
        if let SteelVal::Boxed(c) = val {
×
475
            Some(c)
×
476
        } else {
477
            None
×
478
        }
479
    }
480
}
481

482
impl<'a> PrimitiveAsRef<'a> for &'a HeapRef<SteelVal> {
483
    #[inline(always)]
484
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
13,512,849✔
485
        if let SteelVal::HeapAllocated(b) = val {
27,025,698✔
486
            Ok(b)
×
487
        } else {
488
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel box", val))
×
489
        }
490
    }
491

492
    #[inline(always)]
493
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
494
        if let SteelVal::HeapAllocated(b) = val {
×
495
            Some(b)
×
496
        } else {
497
            None
×
498
        }
499
    }
500
}
501

502
impl<'a> PrimitiveAsRef<'a> for &'a char {
503
    #[inline(always)]
504
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
398✔
505
        if let SteelVal::CharV(c) = val {
796✔
506
            Ok(c)
×
507
        } else {
508
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel character", val))
×
509
        }
510
    }
511

512
    #[inline(always)]
513
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
514
        if let SteelVal::CharV(c) = val {
×
515
            Some(c)
×
516
        } else {
517
            None
×
518
        }
519
    }
520
}
521

522
impl<'a> PrimitiveAsRef<'a> for char {
523
    #[inline(always)]
524
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
15,522✔
525
        if let SteelVal::CharV(c) = val {
31,044✔
526
            Ok(*c)
×
527
        } else {
528
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel character", val))
×
529
        }
530
    }
531

532
    #[inline(always)]
533
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
534
        if let SteelVal::CharV(c) = val {
×
535
            Some(*c)
×
536
        } else {
537
            None
×
538
        }
539
    }
540
}
541

542
impl<'a> PrimitiveAsRef<'a> for isize {
543
    #[inline(always)]
544
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
96✔
545
        if let SteelVal::IntV(i) = val {
192✔
546
            Ok(*i)
×
547
        } else {
548
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel int", val))
×
549
        }
550
    }
551

552
    #[inline(always)]
553
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
554
        if let SteelVal::IntV(i) = val {
×
555
            Some(*i)
×
556
        } else {
557
            None
×
558
        }
559
    }
560
}
561

562
impl<'a> PrimitiveAsRef<'a> for &'a Gc<Vector<SteelVal>> {
563
    #[inline(always)]
564
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
565
        if let SteelVal::VectorV(p) = val {
×
566
            Ok(&p.0)
×
567
        } else {
568
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel vector", val))
×
569
        }
570
    }
571

572
    #[inline(always)]
573
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
574
        if let SteelVal::VectorV(p) = val {
×
575
            Some(&p.0)
×
576
        } else {
577
            None
×
578
        }
579
    }
580
}
581

582
impl<'a> PrimitiveAsRef<'a> for &'a SteelVector {
583
    #[inline(always)]
584
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
8✔
585
        if let SteelVal::VectorV(p) = val {
16✔
586
            Ok(p)
×
587
        } else {
588
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel vector", val))
×
589
        }
590
    }
591

592
    #[inline(always)]
593
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
22✔
594
        if let SteelVal::VectorV(p) = val {
44✔
595
            Some(p)
×
596
        } else {
597
            None
×
598
        }
599
    }
600
}
601

602
impl<'a> PrimitiveAsRef<'a> for &'a Gc<crate::values::HashSet<SteelVal>> {
603
    #[inline(always)]
604
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
605
        if let SteelVal::HashSetV(p) = val {
×
606
            Ok(&p.0)
×
607
        } else {
608
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel hashset", val))
×
609
        }
610
    }
611

612
    #[inline(always)]
613
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
614
        if let SteelVal::HashSetV(p) = val {
×
615
            Some(&p.0)
×
616
        } else {
617
            None
×
618
        }
619
    }
620
}
621

622
impl<'a> PrimitiveAsRef<'a> for &'a SteelHashSet {
623
    #[inline(always)]
624
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
625
        if let SteelVal::HashSetV(p) = val {
×
626
            Ok(p)
×
627
        } else {
628
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel hashset", val))
×
629
        }
630
    }
631

632
    #[inline(always)]
633
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
634
        if let SteelVal::HashSetV(p) = val {
×
635
            Some(p)
×
636
        } else {
637
            None
×
638
        }
639
    }
640
}
641

642
impl<'a> PrimitiveAsRef<'a> for &'a HeapRef<Vec<SteelVal>> {
643
    #[inline(always)]
644
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
2,456,576✔
645
        if let SteelVal::MutableVector(p) = val {
4,913,152✔
646
            Ok(p)
×
647
        } else {
648
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel mutable vector", val))
×
649
        }
650
    }
651

652
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
19✔
653
        if let SteelVal::MutableVector(p) = val {
28✔
654
            Some(p)
×
655
        } else {
656
            None
10✔
657
        }
658
    }
659
}
660

661
impl<'a> PrimitiveAsRef<'a> for &'a SteelPort {
662
    #[inline(always)]
663
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
16,350✔
664
        if let SteelVal::PortV(p) = val {
32,700✔
665
            Ok(p)
×
666
        } else {
667
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel port", val))
×
668
        }
669
    }
670

671
    #[inline(always)]
672
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
673
        if let SteelVal::PortV(p) = val {
×
674
            Some(p)
×
675
        } else {
676
            None
×
677
        }
678
    }
679
}
680

681
impl<'a> PrimitiveAsRef<'a> for &'a List<SteelVal> {
682
    #[inline(always)]
683
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
86,185✔
684
        if let SteelVal::ListV(l) = val {
172,368✔
685
            Ok(l)
×
686
        } else {
687
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to steel list", val))
2✔
688
        }
689
    }
690

691
    #[inline(always)]
692
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
693
        if let SteelVal::ListV(l) = val {
×
694
            Some(l)
×
695
        } else {
696
            None
×
697
        }
698
    }
699
}
700

701
impl<'a> PrimitiveAsRef<'a> for &'a SteelVal {
702
    #[inline(always)]
703
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
16,427✔
704
        Ok(val)
16,427✔
705
    }
706

707
    #[inline(always)]
708
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
709
        Some(val)
×
710
    }
711
}
712

713
impl<'a> PrimitiveAsRefMut<'a> for &'a mut SteelVal {
714
    #[inline(always)]
UNCOV
715
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
×
UNCOV
716
        Ok(val)
×
717
    }
718

719
    #[inline(always)]
720
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
721
        Some(val)
×
722
    }
723
}
724

725
impl<'a> PrimitiveAsRef<'a> for &'a SteelString {
726
    #[inline(always)]
727
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
54,238✔
728
        if let SteelVal::StringV(s) = val {
108,466✔
729
            Ok(s)
×
730
        } else {
731
            crate::stop!(TypeMismatch => format!("Cannot convert steel value: {} to steel string", val))
10✔
732
        }
733
    }
734

735
    #[inline(always)]
736
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
737
        if let SteelVal::StringV(s) = val {
×
738
            Some(s)
×
739
        } else {
740
            None
×
741
        }
742
    }
743
}
744

745
impl<'a> PrimitiveAsRef<'a> for &'a Gc<crate::values::HashMap<SteelVal, SteelVal>> {
746
    #[inline(always)]
747
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
20,850✔
748
        if let SteelVal::HashMapV(hm) = val {
41,700✔
749
            Ok(&hm.0)
×
750
        } else {
751
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
752
        }
753
    }
754

755
    #[inline(always)]
756
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
757
        if let SteelVal::HashMapV(hm) = val {
×
758
            Some(&hm.0)
×
759
        } else {
760
            None
×
761
        }
762
    }
763
}
764

765
impl<'a> PrimitiveAsRefMut<'a> for &'a mut Gc<crate::values::HashMap<SteelVal, SteelVal>> {
766
    #[inline(always)]
767
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
×
768
        if let SteelVal::HashMapV(hm) = val {
×
769
            Ok(&mut hm.0)
×
770
        } else {
771
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
772
        }
773
    }
774

775
    #[inline(always)]
776
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
777
        if let SteelVal::HashMapV(hm) = val {
×
778
            Some(&mut hm.0)
×
779
        } else {
780
            None
×
781
        }
782
    }
783
}
784

785
impl<'a> PrimitiveAsRefMut<'a> for &'a mut SteelByteVector {
786
    #[inline(always)]
787
    fn primitive_as_ref(val: &'a mut SteelVal) -> crate::rvals::Result<Self> {
1✔
788
        if let SteelVal::ByteVector(hm) = val {
2✔
789
            Ok(hm)
×
790
        } else {
791
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to bytevector", val))
×
792
        }
793
    }
794

795
    #[inline(always)]
796
    fn maybe_primitive_as_ref(val: &'a mut SteelVal) -> Option<Self> {
×
797
        if let SteelVal::ByteVector(hm) = val {
×
798
            Some(hm)
×
799
        } else {
800
            None
×
801
        }
802
    }
803
}
804

805
impl<'a> PrimitiveAsRef<'a> for &'a SteelHashMap {
806
    #[inline(always)]
807
    fn primitive_as_ref(val: &'a SteelVal) -> crate::rvals::Result<Self> {
×
808
        if let SteelVal::HashMapV(hm) = val {
×
809
            Ok(hm)
×
810
        } else {
811
            crate::stop!(ConversionError => format!("Cannot convert steel value: {} to hashmap", val))
×
812
        }
813
    }
814

815
    #[inline(always)]
816
    fn maybe_primitive_as_ref(val: &'a SteelVal) -> Option<Self> {
×
817
        if let SteelVal::HashMapV(hm) = val {
×
818
            Some(hm)
×
819
        } else {
820
            None
×
821
        }
822
    }
823
}
824

825
impl IntoSteelVal for String {
826
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
50,557✔
827
        Ok(SteelVal::StringV(self.into()))
50,557✔
828
    }
829
}
830

831
impl IntoSteelVal for SteelString {
832
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
×
833
        Ok(SteelVal::StringV(self))
×
834
    }
835
}
836

837
impl From<String> for Gc<SteelVal> {
838
    fn from(val: String) -> Gc<SteelVal> {
×
839
        Gc::new(val.into())
×
840
    }
841
}
842

843
impl From<bool> for SteelVal {
844
    fn from(val: bool) -> SteelVal {
4,159✔
845
        SteelVal::BoolV(val)
4,159✔
846
    }
847
}
848

849
impl FromSteelVal for bool {
850
    fn from_steelval(val: &SteelVal) -> crate::rvals::Result<bool> {
×
851
        if let SteelVal::BoolV(b) = val {
×
852
            Ok(*b)
853
        } else {
854
            crate::stop!(ConversionError => format!("Cannot convert steel value: {val} to boolean"))
×
855
        }
856
    }
857
}
858

859
impl IntoSteelVal for bool {
860
    fn into_steelval(self) -> Result<SteelVal, SteelErr> {
21,722✔
861
        Ok(SteelVal::BoolV(self))
21,722✔
862
    }
863
}
864

865
impl From<Vector<SteelVal>> for SteelVal {
866
    fn from(val: Vector<SteelVal>) -> SteelVal {
25✔
867
        SteelVal::VectorV(Gc::new(val).into())
25✔
868
    }
869
}
870

871
impl From<FunctionSignature> for SteelVal {
872
    fn from(val: FunctionSignature) -> SteelVal {
×
873
        SteelVal::FuncV(val)
×
874
    }
875
}
876

877
#[cfg(test)]
878
mod try_from_tests {
879

880
    use super::*;
881

882
    #[test]
883
    fn from_char() {
884
        assert_eq!(SteelVal::from('c'), SteelVal::CharV('c'));
885
    }
886

887
    #[test]
888
    fn from_steelval_char() {
889
        assert_eq!(char::from_steelval(&SteelVal::CharV('c')).unwrap(), 'c')
890
    }
891

892
    #[test]
893
    fn into_steelval_char() {
894
        assert_eq!('c'.into_steelval().unwrap(), SteelVal::CharV('c'))
895
    }
896

897
    #[test]
898
    fn from_steelval_usize() {
899
        assert_eq!(usize::from_steelval(&SteelVal::IntV(10)).unwrap(), 10)
900
    }
901

902
    #[test]
903
    fn from_steelval_i32() {
904
        assert_eq!(i32::from_steelval(&SteelVal::IntV(32)).unwrap(), 32)
905
    }
906

907
    #[test]
908
    fn into_steelval_i32() {
909
        assert_eq!(32.into_steelval().unwrap(), SteelVal::IntV(32))
910
    }
911

912
    #[test]
913
    fn from_bool() {
914
        assert_eq!(SteelVal::from(true), SteelVal::BoolV(true));
915
    }
916

917
    #[test]
918
    fn try_from_steelval_string() {
919
        let expected = "foo".to_string();
920
        let input = SteelVal::StringV("foo".into());
921

922
        let res = String::try_from(input);
923
        assert_eq!(res.unwrap(), expected);
924
    }
925

926
    #[test]
927
    fn try_from_steelval_ref_string() {
928
        let expected = "foo".to_string();
929
        let input = SteelVal::StringV("foo".into());
930

931
        let res = String::try_from(&input);
932
        assert_eq!(res.unwrap(), expected);
933
    }
934
}
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