From d0bc225613684ad883d4ac99db083ad888898e15 Mon Sep 17 00:00:00 2001 From: Lucas Clemente Vella Date: Fri, 18 Aug 2023 17:22:20 +0100 Subject: [PATCH] Deterministic serialization of PIL's JSON. (#95) --- starky/src/types.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/starky/src/types.rs b/starky/src/types.rs index 51ccc88a..12a903a1 100644 --- a/starky/src/types.rs +++ b/starky/src/types.rs @@ -1,4 +1,5 @@ #![allow(non_snake_case)] +use serde::ser::SerializeMap; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt; @@ -143,6 +144,7 @@ pub struct PIL { pub nIm: usize, pub nConstants: usize, pub publics: Vec, + #[serde(serialize_with = "ordered_map")] pub references: HashMap, pub expressions: Vec, pub polIdentities: Vec, @@ -156,6 +158,26 @@ pub struct PIL { pub q2exp: Vec, } +/// Sorted serialization of HashMap. +/// +/// For use with serde's [serialize_with] attribute. +fn ordered_map( + value: &HashMap, + serializer: S, +) -> std::result::Result +where + S: serde::Serializer, +{ + let mut ordered = value.iter().collect::>(); + ordered.sort_by_key(|(k, _)| *k); + + let mut map = serializer.serialize_map(Some(ordered.len()))?; + for (k, v) in ordered { + map.serialize_entry(k, v)?; + } + map.end() +} + impl fmt::Display for PIL { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let obj = json!(self);