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
use super::*;
use crate::rust::prelude::*;
use crate::traversal::*;
use crate::*;
use serde::Serializer;
use utils::*;

pub enum SerializationParameters<'s, 'a, E: SerializableCustomExtension> {
    Schemaless {
        mode: SerializationMode,
        custom_context: E::CustomDisplayContext<'a>,
        depth_limit: usize,
    },
    WithSchema {
        mode: SerializationMode,
        custom_context: E::CustomDisplayContext<'a>,
        schema: &'s Schema<E::CustomSchema>,
        type_id: LocalTypeId,
        depth_limit: usize,
    },
}

impl<'s, 'a, E: SerializableCustomExtension> SerializationParameters<'s, 'a, E> {
    pub fn get_context_params(&self) -> (SerializationContext<'s, 'a, E>, LocalTypeId, usize) {
        match self {
            SerializationParameters::Schemaless {
                mode,
                custom_context,
                depth_limit,
            } => (
                SerializationContext {
                    schema: E::CustomSchema::empty_schema(),
                    mode: *mode,
                    custom_context: *custom_context,
                },
                LocalTypeId::any(),
                *depth_limit,
            ),
            SerializationParameters::WithSchema {
                mode,
                custom_context,
                schema,
                type_id,
                depth_limit,
            } => (
                SerializationContext {
                    schema: *schema,
                    mode: *mode,
                    custom_context: *custom_context,
                },
                *type_id,
                *depth_limit,
            ),
        }
    }
}

impl<'s, 'a, 'b, E: SerializableCustomExtension>
    ContextualSerialize<SerializationParameters<'s, 'a, E>> for RawPayload<'b, E>
{
    fn contextual_serialize<S: Serializer>(
        &self,
        serializer: S,
        context: &SerializationParameters<'s, 'a, E>,
    ) -> Result<S::Ok, S::Error> {
        let (context, type_id, depth_limit) = context.get_context_params();
        serialize_payload(
            serializer,
            self.payload_bytes(),
            &context,
            type_id,
            depth_limit,
        )
    }
}

impl<'s, 'a, 'b, E: SerializableCustomExtension>
    ContextualSerialize<SerializationParameters<'s, 'a, E>> for RawValue<'b, E>
{
    fn contextual_serialize<S: Serializer>(
        &self,
        serializer: S,
        context: &SerializationParameters<'s, 'a, E>,
    ) -> Result<S::Ok, S::Error> {
        let (context, type_id, depth_limit) = context.get_context_params();
        serialize_partial_payload(
            serializer,
            self.value_body_bytes(),
            ExpectedStart::ValueBody(self.value_kind()),
            true,
            0,
            &context,
            type_id,
            depth_limit,
        )
    }
}