use crate::types::Type;
use std::fmt::{Display, Formatter, Write};
use std::sync::Arc;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Map {
    pub key_type: Arc<Type>,
    pub value_type: Arc<Type>,
}

impl Map {
    pub fn new(key_type: Type, value_type: Type) -> Map {
        Map {
            key_type: Arc::new(key_type),
            value_type: Arc::new(value_type),
        }
    }

    pub fn fmt_indented(
        &self,
        f: &mut impl Write,
        indentation: usize,
        max_fields: usize,
    ) -> std::fmt::Result {
        write!(f, "map(")?;
        self.key_type.fmt_indented(f, indentation, max_fields)?;
        write!(f, ", ")?;
        self.value_type.fmt_indented(f, indentation, max_fields)?;
        write!(f, ")")
    }

    pub fn subfields(&self) -> usize {
        self.key_type.subfields() + self.value_type.subfields()
    }
}

impl Display for Map {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.fmt_indented(f, 0, usize::MAX)
    }
}
