use super::*;
use sapio_base::simp::{SIMPError, TemplateOutputLT, SIMP};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, JsonSchema, Debug, PartialEq, Eq)]
pub struct OutputMeta {
#[serde(flatten)]
pub extra: BTreeMap<String, serde_json::Value>,
pub simp: BTreeMap<i64, serde_json::Value>,
}
impl OutputMeta {
pub fn is_empty(&self) -> bool {
*self == Default::default()
}
pub fn add_simp<S: SIMPAttachableAt<TemplateOutputLT>>(
mut self,
s: S,
) -> Result<Self, SIMPError> {
let old = self.simp.insert(s.get_protocol_number(), s.to_json()?);
if let Some(old) = old {
Err(SIMPError::AlreadyDefined(old))
} else {
Ok(self)
}
}
}
impl Default for OutputMeta {
fn default() -> Self {
OutputMeta {
extra: Default::default(),
simp: Default::default(),
}
}
}
impl<const N: usize> From<[(&str, serde_json::Value); N]> for OutputMeta {
fn from(v: [(&str, serde_json::Value); N]) -> OutputMeta {
OutputMeta {
extra: IntoIterator::into_iter(v)
.map(|(a, b)| (a.into(), b))
.collect(),
simp: Default::default(),
}
}
}
#[derive(Serialize, Deserialize, JsonSchema, Clone, Debug)]
pub struct Output {
#[serde(with = "bitcoin::util::amount::serde::as_sat")]
#[schemars(with = "i64")]
#[serde(rename = "sending_amount_sats")]
pub amount: Amount,
#[serde(rename = "receiving_contract")]
pub contract: crate::contract::Compiled,
#[serde(
rename = "metadata_map_s2s",
skip_serializing_if = "OutputMeta::is_empty",
default
)]
pub added_metadata: OutputMeta,
}