use std::collections::BTreeMap;
use anyhow::Result;
use super::interface::InterfaceVariant;
#[non_exhaustive]
pub struct Scope {
pub use_nullable_for_merge_patch: bool,
pub variant: Option<InterfaceVariant>,
}
impl Scope {
pub fn with_variant(&self, variant: InterfaceVariant) -> Scope {
Self {
use_nullable_for_merge_patch: self.use_nullable_for_merge_patch,
variant: Some(variant),
}
}
}
impl Default for Scope {
fn default() -> Self {
Self {
use_nullable_for_merge_patch: false,
variant: None,
}
}
}
pub trait Transpile {
type Output: Sized;
fn transpile(&self, scope: &Scope) -> Result<Self::Output>;
}
impl<T> Transpile for Option<T>
where
T: Transpile,
{
type Output = Option<<T as Transpile>::Output>;
fn transpile(&self, scope: &Scope) -> Result<Self::Output> {
match self {
Some(val) => Ok(Some(val.transpile(scope)?)),
None => Ok(None),
}
}
}
impl<T> Transpile for &'_ [T]
where
T: Transpile,
{
type Output = Vec<<T as Transpile>::Output>;
fn transpile(&self, scope: &Scope) -> Result<Self::Output> {
let mut result = vec![];
for elem in self.iter() {
result.push(elem.transpile(scope)?)
}
Ok(result)
}
}
impl<T> Transpile for Vec<T>
where
T: Transpile,
{
type Output = Vec<<T as Transpile>::Output>;
fn transpile(&self, scope: &Scope) -> Result<Self::Output> {
self.as_slice().transpile(scope)
}
}
impl<K, V> Transpile for BTreeMap<K, V>
where
K: Clone + Eq + Ord,
V: Transpile,
{
type Output = BTreeMap<K, <V as Transpile>::Output>;
fn transpile(&self, scope: &Scope) -> Result<Self::Output> {
let mut result = BTreeMap::new();
for (k, v) in self {
result.insert(k.to_owned(), v.transpile(scope)?);
}
Ok(result)
}
}