leo_span/span_json.rs
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
// Copyright (C) 2019-2025 Provable Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
//! Provides custom serialize/deserialize implementations for `Span`.
use crate::Span;
use serde::{
Deserializer,
Serializer,
de::{MapAccess, Visitor},
ser::SerializeMap,
};
use std::fmt;
/// The AST contains a few tuple-like enum variants that contain spans.
/// #[derive(Serialize, Deserialize)] outputs these fields as anonymous
/// mappings, which makes them difficult to remove from the JSON AST.
/// This function provides a custom serialization that maps the keyword
/// `span` to the span information.
pub fn serialize<S: Serializer>(span: &Span, serializer: S) -> Result<S::Ok, S::Error> {
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_entry("span", span)?;
map.end()
}
/// Custom deserialization to enable removing spans from enums.
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Span, D::Error> {
deserializer.deserialize_map(SpanMapVisitor)
}
/// This visitor is used by the deserializer to unwrap mappings
/// and extract span information.
struct SpanMapVisitor;
impl<'de> Visitor<'de> for SpanMapVisitor {
type Value = Span;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("mapping from `span` keyword to span information")
}
fn visit_map<M: MapAccess<'de>>(self, mut access: M) -> Result<Self::Value, M::Error> {
let (_, value): (String, Span) = access.next_entry()?.unwrap();
Ok(value)
}
}