use std::fmt;
use std::fmt::Debug;
use qubit_budget::ResourceQuantity;
use qubit_budget::json::JsonMeasurement;
use qubit_budget::json::JsonValueTransaction;
use serde::de::Error;
use serde::de::Visitor;
pub(super) struct JsonKeyVisitor<'transaction, 'budget, R, Q>
where
Q: ResourceQuantity,
{
transaction: &'transaction mut JsonValueTransaction<'budget, R, Q>,
}
impl<'transaction, 'budget, R, Q> JsonKeyVisitor<'transaction, 'budget, R, Q>
where
R: Clone + Debug,
Q: ResourceQuantity,
{
#[inline]
pub(super) fn new(transaction: &'transaction mut JsonValueTransaction<'budget, R, Q>) -> Self {
Self { transaction }
}
fn visit_borrowed_text<E>(self, value: &str) -> Result<String, E>
where
E: Error,
{
self.transaction
.try_admit(JsonMeasurement::Key { bytes: value.len() })
.map_err(E::custom)?;
Ok(value.to_owned())
}
}
impl<'de, R, Q> Visitor<'de> for JsonKeyVisitor<'_, '_, R, Q>
where
R: Clone + Debug,
Q: ResourceQuantity,
{
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a JSON object key string")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_borrowed_text(value)
}
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_borrowed_text(value)
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: Error,
{
self.transaction
.try_admit(JsonMeasurement::Key { bytes: value.len() })
.map_err(E::custom)?;
Ok(value)
}
}