rune/runtime/
range_full.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use core::cmp::Ordering;
use core::fmt;
use core::ops;

use crate as rune;
use crate::alloc::clone::TryClone;
use crate::runtime::{FromValue, RuntimeError, ToValue, Value, VmResult};
use crate::Any;

/// Type for a full range expression `..`.
///
/// # Examples
///
/// ```rune
/// let range = ..;
///
/// assert!(range.contains(-10));
/// assert!(range.contains(5));
/// assert!(range.contains(10));
/// assert!(range.contains(20));
///
/// assert!(range is std::ops::RangeFull);
/// ```
///
/// # Rust Examples
///
/// ```rust
/// use rune::runtime::RangeFull;
///
/// let _ = RangeFull::new();
/// # Ok::<_, rune::support::Error>(())
/// ```
#[derive(Any, Default, Clone, TryClone)]
#[try_clone(crate)]
#[rune(crate, constructor, item = ::std::ops)]
pub struct RangeFull;

impl RangeFull {
    /// Construct a new full range.
    pub const fn new() -> Self {
        Self
    }

    /// Test if the range contains the given value.
    ///
    /// The check is performed using the [`PARTIAL_CMP`] protocol.
    ///
    /// # Examples
    ///
    /// ```rune
    /// let range = ..;
    ///
    /// assert!(range.contains(-10));
    /// assert!(range.contains(5));
    /// assert!(range.contains(10));
    /// assert!(range.contains(20));
    ///
    /// assert!(range is std::ops::RangeFull);
    /// ```
    #[rune::function(keep)]
    pub(crate) fn contains(&self, _: Value) -> VmResult<bool> {
        VmResult::Ok(true)
    }

    /// Test the full range for partial equality.
    ///
    /// # Examples
    ///
    /// ```rune
    /// let range = ..;
    /// assert!(range == ..);
    /// ```
    #[rune::function(keep, protocol = PARTIAL_EQ)]
    pub fn partial_eq(&self, _: &Self) -> VmResult<bool> {
        VmResult::Ok(true)
    }

    /// Test the full range for total equality.
    ///
    /// # Examples
    ///
    /// ```rune
    /// use std::ops::eq;
    ///
    /// let range = ..;
    /// assert!(eq(range, ..));
    /// ```
    #[rune::function(keep, protocol = EQ)]
    pub fn eq(&self, _: &Self) -> VmResult<bool> {
        VmResult::Ok(true)
    }

    /// Test the full range for partial ordering.
    ///
    /// # Examples
    ///
    /// ```rune
    /// assert!(!((..) < (..)));
    /// assert!(!((..) > (..)));
    /// ```
    #[rune::function(keep, protocol = PARTIAL_CMP)]
    pub fn partial_cmp(&self, _: &Self) -> VmResult<Option<Ordering>> {
        VmResult::Ok(Some(Ordering::Equal))
    }

    /// Test the full range for total ordering.
    ///
    /// # Examples
    ///
    /// ```rune
    /// use std::ops::cmp;
    /// use std::cmp::Ordering;
    ///
    /// assert_eq!(cmp(.., ..), Ordering::Equal);
    /// ```
    #[rune::function(keep, protocol = CMP)]
    pub fn cmp(&self, _: &Self) -> VmResult<Ordering> {
        VmResult::Ok(Ordering::Equal)
    }
}

impl fmt::Debug for RangeFull {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "..")
    }
}

impl ToValue for ops::RangeFull {
    fn to_value(self) -> Result<Value, RuntimeError> {
        let range = RangeFull::new();
        Ok(Value::new(range)?)
    }
}

impl FromValue for ops::RangeFull {
    #[inline]
    fn from_value(value: Value) -> Result<Self, RuntimeError> {
        let RangeFull = value.downcast::<RangeFull>()?;
        Ok(ops::RangeFull)
    }
}