fbthrift_git/
ttype.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use std::collections::BTreeMap;
18use std::collections::BTreeSet;
19use std::collections::HashMap;
20use std::collections::HashSet;
21use std::hash::Hash;
22use std::sync::Arc;
23
24use bytes::Bytes;
25use ordered_float::OrderedFloat;
26
27use crate::errors::ProtocolError;
28use crate::Result;
29
30/// Will be able to add missing types once #![feature(associated_consts)] lands
31#[derive(PartialEq, Copy, Clone, Debug)]
32#[repr(u8)]
33pub enum TType {
34    Stop = 0,
35    Void = 1,
36    Bool = 2,
37    Byte = 3,
38    // I08    = 3,
39    Double = 4,
40    I16 = 6,
41    I32 = 8,
42    I64 = 10,
43    String = 11,
44    // UTF7   = 11,
45    Struct = 12,
46    Map = 13,
47    Set = 14,
48    List = 15,
49    UTF8 = 16,
50    UTF16 = 17,
51    Stream = 18,
52    Float = 19,
53}
54
55impl TryFrom<i8> for TType {
56    type Error = anyhow::Error;
57
58    #[inline]
59    fn try_from(val: i8) -> Result<Self> {
60        let ret = match val {
61            0 => TType::Stop,
62            1 => TType::Void,
63            2 => TType::Bool,
64            3 => TType::Byte,
65            4 => TType::Double,
66            6 => TType::I16,
67            8 => TType::I32,
68            10 => TType::I64,
69            11 => TType::String,
70            12 => TType::Struct,
71            13 => TType::Map,
72            14 => TType::Set,
73            15 => TType::List,
74            16 => TType::UTF8,
75            17 => TType::UTF16,
76            18 => TType::Stream,
77            19 => TType::Float,
78            _ => bail_err!(ProtocolError::InvalidTypeTag),
79        };
80        Ok(ret)
81    }
82}
83
84impl From<TType> for String {
85    fn from(t: TType) -> String {
86        let tmp: &str = t.into();
87        tmp.to_owned()
88    }
89}
90
91impl From<TType> for &'static str {
92    fn from(t: TType) -> &'static str {
93        match t {
94            TType::Stop => "STOP",
95            TType::Void => "VOID",
96            TType::Bool => "BOOL",
97            TType::Byte => "BYTE",
98            // TType::I08 => "I08",
99            TType::Double => "DOUBLE",
100            TType::I16 => "I16",
101            TType::I32 => "I32",
102            TType::I64 => "I64",
103            TType::String => "STRING",
104            // TType::UTF7 => "UTF7",
105            TType::Struct => "STRUCT",
106            TType::Map => "MAP",
107            TType::Set => "SET",
108            TType::List => "LIST",
109            TType::UTF8 => "UTF8",
110            TType::UTF16 => "UTF16",
111            TType::Stream => "STREAM",
112            TType::Float => "FLOAT",
113        }
114    }
115}
116
117// Get the ttype for a given type
118pub trait GetTType {
119    const TTYPE: TType;
120}
121
122impl GetTType for () {
123    const TTYPE: TType = TType::Void;
124}
125
126impl GetTType for bool {
127    const TTYPE: TType = TType::Bool;
128}
129
130impl GetTType for i8 {
131    const TTYPE: TType = TType::Byte;
132}
133
134impl GetTType for i16 {
135    const TTYPE: TType = TType::I16;
136}
137
138impl GetTType for i32 {
139    const TTYPE: TType = TType::I32;
140}
141
142impl GetTType for i64 {
143    const TTYPE: TType = TType::I64;
144}
145
146impl GetTType for f64 {
147    const TTYPE: TType = TType::Double;
148}
149
150impl GetTType for f32 {
151    const TTYPE: TType = TType::Float;
152}
153
154impl GetTType for OrderedFloat<f64> {
155    const TTYPE: TType = TType::Double;
156}
157
158impl GetTType for OrderedFloat<f32> {
159    const TTYPE: TType = TType::Float;
160}
161
162impl GetTType for String {
163    const TTYPE: TType = TType::String;
164}
165
166impl GetTType for Bytes {
167    const TTYPE: TType = TType::String;
168}
169
170// This only narrowly avoids a collision with Vec<T>, because
171// it requires T: GetTType, but u8 does not impl it (only i8).
172impl GetTType for Vec<u8> {
173    const TTYPE: TType = TType::String;
174}
175
176impl<T> GetTType for BTreeSet<T>
177where
178    T: GetTType + Ord,
179{
180    const TTYPE: TType = TType::Set;
181}
182
183impl<T, S> GetTType for HashSet<T, S>
184where
185    T: GetTType + Hash + Eq,
186    S: std::hash::BuildHasher,
187{
188    const TTYPE: TType = TType::Set;
189}
190
191impl<K, V> GetTType for BTreeMap<K, V>
192where
193    K: GetTType + Ord,
194    V: GetTType,
195{
196    const TTYPE: TType = TType::Map;
197}
198
199impl<K, V, S> GetTType for HashMap<K, V, S>
200where
201    K: GetTType + Hash + Eq,
202    V: GetTType,
203    S: std::hash::BuildHasher,
204{
205    const TTYPE: TType = TType::Map;
206}
207
208impl<T> GetTType for Vec<T>
209where
210    T: GetTType,
211{
212    const TTYPE: TType = TType::List;
213}
214
215impl<T> GetTType for Box<T>
216where
217    T: GetTType,
218{
219    const TTYPE: TType = <T as GetTType>::TTYPE;
220}
221
222impl<T> GetTType for Arc<T>
223where
224    T: GetTType,
225{
226    const TTYPE: TType = <T as GetTType>::TTYPE;
227}