1use super::*;
2use std::convert::TryInto;
3
4pub trait TryAsRef<T> {
5 fn try_as_ref(&self) -> Option<&T>;
6}
7
8impl<T> TryAsRef<T> for T {
9 fn try_as_ref(&self) -> Option<&T> {
10 Some(self)
11 }
12}
13
14macro_rules! impl_term_try_as_ref {
15 ($to:ident) => {
16 impl TryAsRef<$to> for Term {
17 fn try_as_ref(&self) -> Option<&$to> {
18 match *self {
19 Term::$to(ref x) => Some(x),
20 _ => None,
21 }
22 }
23 }
24 };
25}
26impl_term_try_as_ref!(Atom);
27impl_term_try_as_ref!(FixInteger);
28impl_term_try_as_ref!(BigInteger);
29impl_term_try_as_ref!(Float);
30impl_term_try_as_ref!(Pid);
31impl_term_try_as_ref!(Port);
32impl_term_try_as_ref!(Reference);
33impl_term_try_as_ref!(ExternalFun);
34impl_term_try_as_ref!(InternalFun);
35impl_term_try_as_ref!(Binary);
36impl_term_try_as_ref!(BitBinary);
37impl_term_try_as_ref!(List);
38impl_term_try_as_ref!(ImproperList);
39impl_term_try_as_ref!(Tuple);
40impl_term_try_as_ref!(Map);
41impl_term_try_as_ref!(ByteList);
42
43macro_rules! impl_term_try_into {
44 ($to:ident) => {
45 impl TryInto<$to> for Term {
46 type Error = Self;
47
48 fn try_into(self) -> Result<$to, Self>
49 where
50 Self: Sized,
51 {
52 match self {
53 Term::$to(x) => Ok(x),
54 _ => Err(self),
55 }
56 }
57 }
58 };
59}
60macro_rules! impl_term_try_into_boxed {
61 ($to:ident) => {
62 impl TryInto<$to> for Term {
63 type Error = Self;
64
65 fn try_into(self) -> Result<$to, Self>
66 where
67 Self: Sized,
68 {
69 match self {
70 Term::$to(x) => Ok(*x),
71 _ => Err(self),
72 }
73 }
74 }
75 };
76}
77impl_term_try_into!(Atom);
78impl_term_try_into!(FixInteger);
79impl_term_try_into!(BigInteger);
80impl_term_try_into!(Float);
81impl_term_try_into!(Pid);
82impl_term_try_into!(Port);
83impl_term_try_into_boxed!(Reference);
84impl_term_try_into_boxed!(ExternalFun);
85impl_term_try_into_boxed!(InternalFun);
86impl_term_try_into!(Binary);
87impl_term_try_into!(BitBinary);
88impl_term_try_into!(List);
89impl_term_try_into!(ImproperList);
90impl_term_try_into!(Tuple);
91impl_term_try_into!(Map);
92impl_term_try_into!(ByteList);
93
94pub trait AsOption {
95 fn as_option(&self) -> Option<&Self>;
96}
97impl AsOption for bool {
98 fn as_option(&self) -> Option<&Self> {
99 if *self { Some(self) } else { None }
100 }
101}
102
103impl num_traits::ToPrimitive for FixInteger {
104 fn to_i64(&self) -> Option<i64> {
105 Some(i64::from(self.value))
106 }
107 fn to_u64(&self) -> Option<u64> {
108 Some(self.value as u64)
109 }
110 fn to_f64(&self) -> Option<f64> {
111 Some(f64::from(self.value))
112 }
113}
114impl num_traits::ToPrimitive for BigInteger {
115 fn to_i64(&self) -> Option<i64> {
116 self.value.to_i64()
117 }
118 fn to_u64(&self) -> Option<u64> {
119 self.value.to_u64()
120 }
121 fn to_f64(&self) -> Option<f64> {
122 self.value.to_f64()
123 }
124}
125impl num_traits::ToPrimitive for Float {
126 fn to_i64(&self) -> Option<i64> {
127 None
128 }
129 fn to_u64(&self) -> Option<u64> {
130 None
131 }
132 fn to_f64(&self) -> Option<f64> {
133 Some(self.value)
134 }
135}
136impl num_traits::ToPrimitive for Term {
137 fn to_i64(&self) -> Option<i64> {
138 match *self {
139 Term::FixInteger(ref x) => x.to_i64(),
140 Term::BigInteger(ref x) => x.to_i64(),
141 _ => None,
142 }
143 }
144 fn to_u64(&self) -> Option<u64> {
145 match *self {
146 Term::FixInteger(ref x) => x.to_u64(),
147 Term::BigInteger(ref x) => x.to_u64(),
148 _ => None,
149 }
150 }
151 fn to_f64(&self) -> Option<f64> {
152 match *self {
153 Term::FixInteger(ref x) => x.to_f64(),
154 Term::BigInteger(ref x) => x.to_f64(),
155 Term::Float(ref x) => x.to_f64(),
156 _ => None,
157 }
158 }
159}
160
161impl num_bigint::ToBigInt for FixInteger {
162 fn to_bigint(&self) -> Option<num_bigint::BigInt> {
163 Some(BigInteger::from(self).value)
164 }
165}
166impl num_bigint::ToBigInt for BigInteger {
167 fn to_bigint(&self) -> Option<num_bigint::BigInt> {
168 Some(self.value.clone())
169 }
170}
171impl num_bigint::ToBigInt for Term {
172 fn to_bigint(&self) -> Option<num_bigint::BigInt> {
173 match *self {
174 Term::FixInteger(ref x) => x.to_bigint(),
175 Term::BigInteger(ref x) => x.to_bigint(),
176 _ => None,
177 }
178 }
179}
180
181impl num_bigint::ToBigUint for FixInteger {
182 fn to_biguint(&self) -> Option<num_bigint::BigUint> {
183 BigInteger::from(self).value.to_biguint()
184 }
185}
186impl num_bigint::ToBigUint for BigInteger {
187 fn to_biguint(&self) -> Option<num_bigint::BigUint> {
188 self.value.to_biguint()
189 }
190}
191impl num_bigint::ToBigUint for Term {
192 fn to_biguint(&self) -> Option<num_bigint::BigUint> {
193 match *self {
194 Term::FixInteger(ref x) => x.to_biguint(),
195 Term::BigInteger(ref x) => x.to_biguint(),
196 _ => None,
197 }
198 }
199}