1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! This module contains the actual code generation logic

use std::fmt::{Display, Formatter};
use std::io::{Result, Write};

mod enumeration;
mod message;

pub use enumeration::generate_enum;
pub use message::generate_message;

#[derive(Debug, Clone, Copy)]
struct Indent(usize);

impl Display for Indent {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        for _ in 0..self.0 {
            write!(f, "    ")?;
        }
        Ok(())
    }
}

fn write_fields_array<'a, W: Write, I: Iterator<Item = &'a str>>(
    writer: &mut W,
    indent: usize,
    variants: I,
) -> Result<()> {
    writeln!(writer, "{}const FIELDS: &[&str] = &[", Indent(indent))?;
    for name in variants {
        writeln!(writer, "{}\"{}\",", Indent(indent + 1), name)?;
    }
    writeln!(writer, "{}];", Indent(indent))?;
    writeln!(writer)
}

fn write_serialize_start<W: Write>(indent: usize, rust_type: &str, writer: &mut W) -> Result<()> {
    writeln!(
        writer,
        r#"{indent}impl serde::Serialize for {rust_type} {{
{indent}    #[allow(deprecated)]
{indent}    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
{indent}    where
{indent}        S: serde::Serializer,
{indent}    {{"#,
        indent = Indent(indent),
        rust_type = rust_type
    )
}

fn write_serialize_end<W: Write>(indent: usize, writer: &mut W) -> Result<()> {
    writeln!(
        writer,
        r#"{indent}    }}
{indent}}}"#,
        indent = Indent(indent),
    )
}

fn write_deserialize_start<W: Write>(indent: usize, rust_type: &str, writer: &mut W) -> Result<()> {
    writeln!(
        writer,
        r#"{indent}impl<'de> serde::Deserialize<'de> for {rust_type} {{
{indent}    #[allow(deprecated)]
{indent}    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
{indent}    where
{indent}        D: serde::Deserializer<'de>,
{indent}    {{"#,
        indent = Indent(indent),
        rust_type = rust_type
    )
}

fn write_deserialize_end<W: Write>(indent: usize, writer: &mut W) -> Result<()> {
    writeln!(
        writer,
        r#"{indent}    }}
{indent}}}"#,
        indent = Indent(indent),
    )
}