1use std::fmt;2use std::ops::Deref;3use std::rc::Rc;45use jrsonnet_gcmodule::Acyclic;6use jrsonnet_interner::IStr;78#[derive(Clone, Acyclic, Debug, PartialEq, Eq)]9pub struct ParamName(pub Option<IStr>);10impl ParamName {11 pub const ANONYMOUS: Self = Self(None);12 pub fn new(name: IStr) -> Self {13 Self(Some(name))14 }15 pub fn as_str(&self) -> Option<&str> {16 self.0.as_deref()17 }18 pub fn is_anonymous(&self) -> bool {19 self.0.is_none()20 }21}22impl PartialEq<IStr> for ParamName {23 fn eq(&self, other: &IStr) -> bool {24 self.025 .as_ref()26 .map_or(false, |s| s.as_bytes() == other.as_bytes())27 }28}2930impl fmt::Display for ParamName {31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {32 match &self.0 {33 Some(v) => write!(f, "{v}"),34 None => write!(f, "<unnamed>"),35 }36 }37}3839#[derive(Clone, Copy, Debug, Acyclic, PartialEq, Eq)]40pub enum ParamDefault {41 None,42 Exists,43 Literal(&'static str),44}45impl ParamDefault {46 pub const fn exists(is_exists: bool) -> Self {47 if is_exists {48 Self::Exists49 } else {50 Self::None51 }52 }53}54impl fmt::Display for ParamDefault {55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {56 match self {57 ParamDefault::None => Ok(()),58 ParamDefault::Exists => write!(f, " = <default>"),59 ParamDefault::Literal(lit) => write!(f, " = {lit}"),60 }61 }62}6364#[derive(Clone, Acyclic, Debug, PartialEq, Eq)]65pub struct ParamParse {66 name: ParamName,67 default: ParamDefault,68}69impl ParamParse {70 pub fn new(name: ParamName, default: ParamDefault) -> Self {71 Self { name, default }72 }73 74 pub fn name(&self) -> &ParamName {75 &self.name76 }77 pub fn default(&self) -> ParamDefault {78 self.default79 }80 pub fn has_default(&self) -> bool {81 !matches!(self.default, ParamDefault::None)82 }83}84impl fmt::Display for ParamParse {85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {86 write!(f, "{}{}", self.name, self.default)87 }88}8990#[derive(Debug, Clone, Acyclic, PartialEq, Eq)]91pub struct FunctionSignature(Rc<[ParamParse]>);92impl Deref for FunctionSignature {93 type Target = [ParamParse];9495 fn deref(&self) -> &Self::Target {96 &self.097 }98}99100thread_local! {101 static EMPTY_SIGNATURE: FunctionSignature = FunctionSignature::new([].into());102}103104impl FunctionSignature {105 pub fn new(v: Rc<[ParamParse]>) -> Self {106 Self(v)107 }108 pub fn empty() -> Self {109 EMPTY_SIGNATURE.with(|p| p.clone())110 }111}112impl fmt::Display for FunctionSignature {113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {114 if self.0.is_empty() {115 return write!(f, "(/*no arguments*/)");116 }117 write!(f, "(")?;118 for (i, par) in self.0.iter().enumerate() {119 if i != 0 {120 write!(f, ", ")?;121 }122 write!(f, "{par}")?;123 }124 write!(f, ")")125 }126}