substrate_data/schema/plain/
ints.rs1use crate::binary::{Decoder, Writer};
4use crate::frame::{Packer, Unpacker};
5use crate::model::borrowed::ValueRef;
6use crate::model::value::Value;
7use crate::schema::{Expected, Reader, Schema, Shape};
8
9trait Int: Copy + Sized {
12 fn range() -> (i64, i64);
14 fn to_i64(self) -> i64;
16 fn of_i64(n: i64) -> Option<Self>;
18 fn to_bits(self) -> u64;
20 fn of_bits(v: u64) -> Option<Self>;
22}
23
24macro_rules! signed {
25 ($($t:ty),*) => {$(
26 impl Int for $t {
27 fn range() -> (i64, i64) {
28 (i64::from(<$t>::MIN), i64::from(<$t>::MAX))
29 }
30 fn to_i64(self) -> i64 {
31 i64::from(self)
32 }
33 fn of_i64(n: i64) -> Option<Self> {
34 Self::try_from(n).ok()
35 }
36 fn to_bits(self) -> u64 {
37 crate::binary::zigzag(i64::from(self))
38 }
39 fn of_bits(v: u64) -> Option<Self> {
40 Self::try_from(crate::binary::unzigzag(v)).ok()
41 }
42 }
43 )*};
44}
45signed!(i8, i16, i32, i64);
46
47macro_rules! unsigned {
48 ($($t:ty),*) => {$(
49 impl Int for $t {
50 fn range() -> (i64, i64) {
51 (0, i64::from(<$t>::MAX))
52 }
53 fn to_i64(self) -> i64 {
54 i64::from(self)
55 }
56 fn of_i64(n: i64) -> Option<Self> {
57 Self::try_from(n).ok()
58 }
59 fn to_bits(self) -> u64 {
60 u64::from(self)
61 }
62 fn of_bits(v: u64) -> Option<Self> {
63 Self::try_from(v).ok()
64 }
65 }
66 )*};
67}
68unsigned!(u8, u16, u32);
69
70impl Int for u64 {
71 fn range() -> (i64, i64) {
72 (0, i64::MAX)
73 }
74 fn to_i64(self) -> i64 {
75 i64::from_ne_bytes(self.to_ne_bytes())
76 }
77 fn of_i64(n: i64) -> Option<Self> {
78 Some(u64::from_ne_bytes(n.to_ne_bytes()))
79 }
80 fn to_bits(self) -> u64 {
81 self
82 }
83 fn of_bits(v: u64) -> Option<Self> {
84 Some(v)
85 }
86}
87
88impl Int for usize {
89 fn range() -> (i64, i64) {
90 (0, i64::MAX)
91 }
92 fn to_i64(self) -> i64 {
93 u64::try_from(self).unwrap_or(u64::MAX).to_i64()
94 }
95 fn of_i64(n: i64) -> Option<Self> {
96 Self::try_from(u64::of_i64(n)?).ok()
97 }
98 fn to_bits(self) -> u64 {
99 u64::try_from(self).unwrap_or(u64::MAX)
100 }
101 fn of_bits(v: u64) -> Option<Self> {
102 Self::try_from(v).ok()
103 }
104}
105
106macro_rules! int_schema {
107 ($($t:ty),*) => {$(
108 impl Schema for $t {
109 fn shape() -> Shape {
110 let (min, max) = <$t as Int>::range();
111 Shape::Int { min, max }
112 }
113 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
114 let Some(n) = v.as_i64() else {
115 cx.expected(Expected::Integer, v);
116 return None;
117 };
118 <$t as Int>::of_i64(n).or_else(|| {
119 cx.problem(format!("{n} is out of range ({}..={})", <$t>::MIN, <$t>::MAX));
120 None
121 })
122 }
123 fn write(&self) -> Value {
124 Value::Int(self.to_i64())
125 }
126 fn encode(&self, w: &mut Writer) {
127 w.int(self.to_i64());
128 }
129 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
130 d.int().and_then(<$t as Int>::of_i64)
131 }
132 fn pack(&self, p: &mut Packer) {
133 p.put_i(self.to_i64());
134 }
135 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
136 u.int().and_then(<$t as Int>::of_i64)
137 }
138 fn pack_list(items: &[Self], p: &mut Packer) {
139 p.put_uints(items.len(), items.iter().map(|&n| n.to_bits()));
140 }
141 fn unpack_list(u: &mut Unpacker<'_>) -> Option<Vec<Self>> {
142 u.uints(<$t as Int>::of_bits)
143 }
144 fn encode_list(items: &[Self], w: &mut Writer) {
145 w.ints(items.iter().map(|&n| n.to_i64()));
146 }
147 fn decode_list(d: &mut Decoder<'_>) -> Option<Vec<Self>> {
148 let n = d.ints()?;
149 let mut out = Vec::with_capacity(n);
150 for _ in 0..n {
151 out.push(<$t as Int>::of_i64(d.packed_int()?)?);
152 }
153 Some(out)
154 }
155 }
156 )*};
157}
158int_schema!(i8, i16, i32, i64, u8, u16, u32, u64, usize);