rune/runtime/range_full.rs
1use core::cmp::Ordering;
2use core::fmt;
3use core::ops;
4
5use crate as rune;
6use crate::alloc::clone::TryClone;
7use crate::runtime::{FromValue, RuntimeError, ToValue, Value, VmResult};
8use crate::Any;
9
10/// Type for a full range expression `..`.
11///
12/// # Examples
13///
14/// ```rune
15/// let range = ..;
16///
17/// assert!(range.contains(-10));
18/// assert!(range.contains(5));
19/// assert!(range.contains(10));
20/// assert!(range.contains(20));
21///
22/// assert!(range is std::ops::RangeFull);
23/// ```
24///
25/// # Rust Examples
26///
27/// ```rust
28/// use rune::runtime::RangeFull;
29///
30/// let _ = RangeFull::new();
31/// # Ok::<_, rune::support::Error>(())
32/// ```
33#[derive(Any, Default, Clone, TryClone)]
34#[try_clone(crate)]
35#[rune(crate, constructor, item = ::std::ops)]
36pub struct RangeFull;
37
38impl RangeFull {
39 /// Construct a new full range.
40 pub const fn new() -> Self {
41 Self
42 }
43
44 /// Test if the range contains the given value.
45 ///
46 /// The check is performed using the [`PARTIAL_CMP`] protocol.
47 ///
48 /// # Examples
49 ///
50 /// ```rune
51 /// let range = ..;
52 ///
53 /// assert!(range.contains(-10));
54 /// assert!(range.contains(5));
55 /// assert!(range.contains(10));
56 /// assert!(range.contains(20));
57 ///
58 /// assert!(range is std::ops::RangeFull);
59 /// ```
60 #[rune::function(keep)]
61 pub(crate) fn contains(&self, _: Value) -> VmResult<bool> {
62 VmResult::Ok(true)
63 }
64
65 /// Test the full range for partial equality.
66 ///
67 /// # Examples
68 ///
69 /// ```rune
70 /// let range = ..;
71 /// assert!(range == ..);
72 /// ```
73 #[rune::function(keep, protocol = PARTIAL_EQ)]
74 pub fn partial_eq(&self, _: &Self) -> VmResult<bool> {
75 VmResult::Ok(true)
76 }
77
78 /// Test the full range for total equality.
79 ///
80 /// # Examples
81 ///
82 /// ```rune
83 /// use std::ops::eq;
84 ///
85 /// let range = ..;
86 /// assert!(eq(range, ..));
87 /// ```
88 #[rune::function(keep, protocol = EQ)]
89 pub fn eq(&self, _: &Self) -> VmResult<bool> {
90 VmResult::Ok(true)
91 }
92
93 /// Test the full range for partial ordering.
94 ///
95 /// # Examples
96 ///
97 /// ```rune
98 /// assert!(!((..) < (..)));
99 /// assert!(!((..) > (..)));
100 /// ```
101 #[rune::function(keep, protocol = PARTIAL_CMP)]
102 pub fn partial_cmp(&self, _: &Self) -> VmResult<Option<Ordering>> {
103 VmResult::Ok(Some(Ordering::Equal))
104 }
105
106 /// Test the full range for total ordering.
107 ///
108 /// # Examples
109 ///
110 /// ```rune
111 /// use std::ops::cmp;
112 /// use std::cmp::Ordering;
113 ///
114 /// assert_eq!(cmp(.., ..), Ordering::Equal);
115 /// ```
116 #[rune::function(keep, protocol = CMP)]
117 pub fn cmp(&self, _: &Self) -> VmResult<Ordering> {
118 VmResult::Ok(Ordering::Equal)
119 }
120}
121
122impl fmt::Debug for RangeFull {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 write!(f, "..")
125 }
126}
127
128impl ToValue for ops::RangeFull {
129 fn to_value(self) -> Result<Value, RuntimeError> {
130 let range = RangeFull::new();
131 Ok(Value::new(range)?)
132 }
133}
134
135impl FromValue for ops::RangeFull {
136 #[inline]
137 fn from_value(value: Value) -> Result<Self, RuntimeError> {
138 let RangeFull = value.downcast::<RangeFull>()?;
139 Ok(ops::RangeFull)
140 }
141}