pub struct StratumRequest<State> {
    pub(crate) state: State,
    pub(crate) values: serde_json::map::Map<String, serde_json::Value>,
}

impl<State> StratumRequest<State> {
    ///  Access application scoped state.
    pub fn state(&self) -> &State {
        &self.state
    }

    pub fn get(&self, name: &str) -> Option<&serde_json::Value> {
        self.values.get(name)
    }

    pub fn get_json<T: serde::de::DeserializeOwned>(
        &self,
        name: &str,
    ) -> Result<T, serde_json::Error> {
        let value = self
            .values
            .get(name)
            .ok_or_else(|| serde::de::Error::custom(format!("expected {}", name)))?
            .clone();

        Ok(serde_json::from_value(value)?)
    }
}
