blob: a1b457f34f0a5a0994d2dad83053ab5b5d5b8e4f [file] [log] [blame] [edit]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use core::fmt;
use core::hash::Hash;
use core::marker::PhantomData;
use std::collections::HashMap;
use serde::de::{SeqAccess, Visitor};
use serde::{Deserialize, Deserializer};
pub trait Index {
type Key: Clone + Hash + Eq;
fn key(&self) -> &Self::Key;
}
pub fn index<'de, D, T>(deserializer: D) -> Result<HashMap<T::Key, T>, D::Error>
where
D: Deserializer<'de>,
T: Index + Deserialize<'de>,
{
struct IndexVisitor<T> {
marker: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for IndexVisitor<T>
where
T: Index + Deserialize<'de>,
{
type Value = HashMap<T::Key, T>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = HashMap::new();
while let Some(value) = seq.next_element::<T>()? {
values.insert(value.key().clone(), value);
}
Ok(values)
}
}
let visitor = IndexVisitor { marker: PhantomData };
deserializer.deserialize_seq(visitor)
}