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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use serde::{
    ser::{self, SerializeStruct, SerializeTuple},
    Serialize,
};

use crate::{
    error::Ensure,
    ser::access::r#enum::Delegate,
    value::{JsoncValue, MapImpl},
};

use super::{
    map::{ValueMapKeySerializer, ValueMapSerializer},
    seq::ValueSeqSerializer,
};

pub struct ValueEnumSerializer<I, F> {
    key: String,
    delegate: Delegate<ValueSeqSerializer<I, F>, ValueMapSerializer<I, F>>,
}

impl<I, F> ValueEnumSerializer<I, F> {
    pub fn start_newtype_variant<S: ser::Serializer, T: ?Sized>(
        serializer: S,
        variant: &'static str,
        value: &T,
    ) -> crate::Result<JsoncValue<I, F>>
    where
        JsoncValue<I, F>: From<S::Ok>,
        crate::Error: From<S::Error>,
        T: ser::Serialize,
    {
        let key = variant.serialize(ValueMapKeySerializer)?;
        Ok(JsoncValue::Object(MapImpl::from_iter([(key, value.serialize(serializer)?.into())])))
    }

    pub fn start_tuple_variant(variant: &str, len: usize) -> crate::Result<Self> {
        Self::start(variant, len, Delegate::<_, ()>::Seq(()))
    }

    pub fn start_struct_variant(variant: &str, len: usize) -> crate::Result<Self> {
        Self::start(variant, len, Delegate::<(), _>::Map(()))
    }

    fn start<S, M>(variant: &str, len: usize, delegate_type: Delegate<S, M>) -> crate::Result<Self> {
        let key = variant.serialize(ValueMapKeySerializer)?;
        let delegate = match delegate_type {
            Delegate::Seq(_) => Delegate::Seq(ValueSeqSerializer::start(Some(len))?),
            Delegate::Map(_) => Delegate::Map(ValueMapSerializer::start(Some(len))?),
        };
        Ok(Self { key, delegate })
    }
}

impl<I, F> ser::SerializeTupleVariant for ValueEnumSerializer<I, F>
where
    I: num::FromPrimitive,
    F: num::FromPrimitive,
{
    type Ok = JsoncValue<I, F>;
    type Error = crate::Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: ser::Serialize,
    {
        match &mut self.delegate {
            Delegate::Seq(seq) => seq.serialize_element(value),
            Delegate::Map(_) => Err(Ensure::SeqLikeVariant)?,
        }
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        let value = match self.delegate {
            Delegate::Seq(seq) => seq.end()?,
            Delegate::Map(_) => Err(Ensure::SeqLikeVariant)?,
        };
        Ok(JsoncValue::Object(MapImpl::from_iter([(self.key, value)])))
    }
}

impl<I, F> ser::SerializeStructVariant for ValueEnumSerializer<I, F>
where
    I: num::FromPrimitive,
    F: num::FromPrimitive,
{
    type Ok = JsoncValue<I, F>;
    type Error = crate::Error;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
    where
        T: ser::Serialize,
    {
        match &mut self.delegate {
            Delegate::Seq(_) => Err(Ensure::MapLikeVariant)?,
            Delegate::Map(map) => map.serialize_field(key, value),
        }
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        let value = match self.delegate {
            Delegate::Seq(_) => Err(Ensure::MapLikeVariant)?,
            Delegate::Map(map) => map.end()?,
        };
        Ok(JsoncValue::Object(MapImpl::from_iter([(self.key, value)])))
    }
}