slicec/grammar/elements/
primitive.rs

1// Copyright (c) ZeroC, Inc.
2
3use super::super::*;
4use crate::supported_encodings::SupportedEncodings;
5
6#[derive(Debug, PartialEq, Eq)]
7pub enum Primitive {
8    Bool,
9    Int8,
10    UInt8,
11    Int16,
12    UInt16,
13    Int32,
14    UInt32,
15    VarInt32,
16    VarUInt32,
17    Int64,
18    UInt64,
19    VarInt62,
20    VarUInt62,
21    Float32,
22    Float64,
23    String,
24    AnyClass,
25}
26
27impl Primitive {
28    pub fn is_numeric(&self) -> bool {
29        matches!(
30            self,
31            Self::Int8
32                | Self::UInt8
33                | Self::Int16
34                | Self::UInt16
35                | Self::Int32
36                | Self::UInt32
37                | Self::VarInt32
38                | Self::VarUInt32
39                | Self::Int64
40                | Self::UInt64
41                | Self::VarInt62
42                | Self::VarUInt62
43                | Self::Float32
44                | Self::Float64
45        )
46    }
47
48    pub fn is_integral(&self) -> bool {
49        matches!(
50            self,
51            Self::Int8
52                | Self::UInt8
53                | Self::Int16
54                | Self::UInt16
55                | Self::Int32
56                | Self::UInt32
57                | Self::VarInt32
58                | Self::VarUInt32
59                | Self::Int64
60                | Self::UInt64
61                | Self::VarInt62
62                | Self::VarUInt62
63        )
64    }
65
66    pub fn is_unsigned_numeric(&self) -> bool {
67        matches!(
68            self,
69            Self::UInt8 | Self::UInt16 | Self::UInt32 | Self::VarUInt32 | Self::UInt64 | Self::VarUInt62
70        )
71    }
72
73    pub fn numeric_bounds(&self) -> Option<(i128, i128)> {
74        const VARINT62_MIN: i128 = -2_305_843_009_213_693_952; // -2^61
75        const VARINT62_MAX: i128 = 2_305_843_009_213_693_951; // 2^61 - 1
76        const VARUINT62_MAX: i128 = 4_611_686_018_427_387_903; // 2^62 - 1
77
78        match self {
79            Self::Int8 => Some((i8::MIN as i128, i8::MAX as i128)),
80            Self::UInt8 => Some((0, u8::MAX as i128)),
81            Self::Int16 => Some((i16::MIN as i128, i16::MAX as i128)),
82            Self::UInt16 => Some((0, u16::MAX as i128)),
83            Self::Int32 => Some((i32::MIN as i128, i32::MAX as i128)),
84            Self::UInt32 => Some((0, u32::MAX as i128)),
85            Self::VarInt32 => Some((i32::MIN as i128, i32::MAX as i128)),
86            Self::VarUInt32 => Some((0, u32::MAX as i128)),
87            Self::Int64 => Some((i64::MIN as i128, i64::MAX as i128)),
88            Self::UInt64 => Some((0, u64::MAX as i128)),
89            Self::VarInt62 => Some((VARINT62_MIN, VARINT62_MAX)),
90            Self::VarUInt62 => Some((0, VARUINT62_MAX)),
91            _ => None,
92        }
93    }
94}
95
96impl Type for Primitive {
97    fn type_string(&self) -> String {
98        self.kind().to_owned()
99    }
100
101    fn fixed_wire_size(&self) -> Option<u32> {
102        match self {
103            Self::Bool => Some(1),
104            Self::Int8 => Some(1),
105            Self::UInt8 => Some(1),
106            Self::Int16 => Some(2),
107            Self::UInt16 => Some(2),
108            Self::Int32 => Some(4),
109            Self::UInt32 => Some(4),
110            Self::VarInt32 => None,
111            Self::VarUInt32 => None,
112            Self::Int64 => Some(8),
113            Self::UInt64 => Some(8),
114            Self::VarInt62 => None,
115            Self::VarUInt62 => None,
116            Self::Float32 => Some(4),
117            Self::Float64 => Some(8),
118            Self::String => None,
119            Self::AnyClass => None,
120        }
121    }
122
123    fn is_class_type(&self) -> bool {
124        matches!(self, Self::AnyClass)
125    }
126
127    fn tag_format(&self) -> Option<TagFormat> {
128        match self {
129            Self::Bool => Some(TagFormat::F1),
130            Self::Int8 => None,
131            Self::UInt8 => Some(TagFormat::F1),
132            Self::Int16 => Some(TagFormat::F2),
133            Self::UInt16 => None,
134            Self::Int32 => Some(TagFormat::F4),
135            Self::UInt32 => None,
136            Self::VarInt32 => None,
137            Self::VarUInt32 => None,
138            Self::Int64 => Some(TagFormat::F8),
139            Self::UInt64 => None,
140            Self::VarInt62 => None,
141            Self::VarUInt62 => None,
142            Self::Float32 => Some(TagFormat::F4),
143            Self::Float64 => Some(TagFormat::F8),
144            Self::String => Some(TagFormat::OptimizedVSize),
145            Self::AnyClass => Some(TagFormat::Class),
146        }
147    }
148
149    fn supported_encodings(&self) -> SupportedEncodings {
150        SupportedEncodings::new(match self {
151            Self::Bool => vec![Encoding::Slice1, Encoding::Slice2],
152            Self::Int8 => vec![Encoding::Slice2],
153            Self::UInt8 => vec![Encoding::Slice1, Encoding::Slice2],
154            Self::Int16 => vec![Encoding::Slice1, Encoding::Slice2],
155            Self::UInt16 => vec![Encoding::Slice2],
156            Self::Int32 => vec![Encoding::Slice1, Encoding::Slice2],
157            Self::UInt32 => vec![Encoding::Slice2],
158            Self::VarInt32 => vec![Encoding::Slice2],
159            Self::VarUInt32 => vec![Encoding::Slice2],
160            Self::Int64 => vec![Encoding::Slice1, Encoding::Slice2],
161            Self::UInt64 => vec![Encoding::Slice2],
162            Self::VarInt62 => vec![Encoding::Slice2],
163            Self::VarUInt62 => vec![Encoding::Slice2],
164            Self::Float32 => vec![Encoding::Slice1, Encoding::Slice2],
165            Self::Float64 => vec![Encoding::Slice1, Encoding::Slice2],
166            Self::String => vec![Encoding::Slice1, Encoding::Slice2],
167            Self::AnyClass => vec![Encoding::Slice1],
168        })
169    }
170}
171
172impl Element for Primitive {
173    fn kind(&self) -> &'static str {
174        match self {
175            Self::Bool => "bool",
176            Self::Int8 => "int8",
177            Self::UInt8 => "uint8",
178            Self::Int16 => "int16",
179            Self::UInt16 => "uint16",
180            Self::Int32 => "int32",
181            Self::UInt32 => "uint32",
182            Self::VarInt32 => "varint32",
183            Self::VarUInt32 => "varuint32",
184            Self::Int64 => "int64",
185            Self::UInt64 => "uint64",
186            Self::VarInt62 => "varint62",
187            Self::VarUInt62 => "varuint62",
188            Self::Float32 => "float32",
189            Self::Float64 => "float64",
190            Self::String => "string",
191            Self::AnyClass => "AnyClass",
192        }
193    }
194}