ice_rs/slice/
enumeration.rs1use quote::{__private::TokenStream, format_ident, quote};
2
3#[derive(Clone, Debug)]
4pub struct Enum {
5 pub id: TokenStream,
6 pub ice_id: String,
7 variants: Vec<TokenStream>,
8 next_value: i32
9}
10
11impl Enum {
12 pub fn empty() -> Enum {
13 Enum {
14 id: TokenStream::new(),
15 ice_id: String::new(),
16 variants: vec![],
17 next_value: 0
18 }
19 }
20
21 pub fn add_variant(&mut self, name: &str, value: Option<i32>) {
22 let value = match value {
23 Some(value) => {
24 self.next_value = value + 1;
25 value
26 },
27 None => {
28 let value = self.next_value;
29 self.next_value = value + 1;
30 value
31 }
32 };
33 let id = format_ident!("{}", name);
34 self.variants.push(quote! {
35 #id = #value
36 });
37 }
38
39 pub fn generate(&self) -> Result<TokenStream, Box<dyn std::error::Error>> {
40 let id_token = &self.id;
41 let variant_tokens = self.variants.iter().map(|variant| {
42 quote! {
43 #variant
44 }
45 }).collect::<Vec<_>>();
46
47 Ok(quote! {
48 #[derive(Debug, Copy, Clone, TryFromPrimitive, PartialEq)]
49 #[repr(i32)]
50 pub enum #id_token {
51 #(#variant_tokens),*
52 }
53
54 impl OptionalType for #id_token {
55 fn optional_type() -> u8 {
56 4
57 }
58 }
59
60 impl ToBytes for #id_token {
61 fn to_bytes(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
62 let mut bytes = Vec::new();
63 bytes.extend(IceSize{size: *self as i32}.to_bytes()?);
64 Ok(bytes)
65 }
66 }
67
68 impl FromBytes for #id_token {
69 fn from_bytes(bytes: &[u8], read_bytes: &mut i32) -> Result<Self, Box<dyn std::error::Error + Send + Sync>>
70 where Self: Sized {
71 let mut read = 0;
72 let enum_value = IceSize::from_bytes(&bytes[read as usize..bytes.len()], &mut read)?.size;
73 *read_bytes = *read_bytes + read;
74 match #id_token::try_from(enum_value) {
75 Ok(enum_type) => Ok(enum_type),
76 _ => Err(Box::new(ProtocolError::new(&format!("Cannot convert int {} to enum", enum_value))))
77 }
78 }
79 }
80 })
81 }
82}