uiua/
function.rs

1use std::{fmt, hash::Hash};
2
3use serde::*;
4
5use crate::{CodeSpan, Ident, Primitive, Signature};
6
7/// A function that executes Rust code
8#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9pub struct DynamicFunction {
10    /// An index used to look up the function
11    pub(crate) index: usize,
12    /// The function's signature
13    pub(crate) sig: Signature,
14}
15
16impl From<(usize, Signature)> for DynamicFunction {
17    fn from((index, sig): (usize, Signature)) -> Self {
18        Self { index, sig }
19    }
20}
21
22impl From<DynamicFunction> for (usize, Signature) {
23    fn from(func: DynamicFunction) -> Self {
24        (func.index, func.sig)
25    }
26}
27
28impl DynamicFunction {
29    /// Get the function's signature
30    pub fn signature(&self) -> Signature {
31        self.sig
32    }
33}
34
35impl fmt::Debug for DynamicFunction {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "<dynamic#{:x}>", self.index)
38    }
39}
40
41/// A Uiua function id
42#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
43#[serde(untagged)]
44pub enum FunctionId {
45    /// Just a primitive
46    Primitive(Primitive),
47    /// A named function
48    Named(Ident),
49    /// A macro expansion
50    Macro(Option<Ident>, CodeSpan),
51    /// The top-level function
52    Main,
53    #[doc(hidden)]
54    /// Implementation detail
55    Unnamed,
56}
57
58impl PartialEq<&str> for FunctionId {
59    fn eq(&self, other: &&str) -> bool {
60        match self {
61            FunctionId::Named(name) => &&**name == other,
62            _ => false,
63        }
64    }
65}
66
67impl From<Ident> for FunctionId {
68    fn from(name: Ident) -> Self {
69        Self::Named(name)
70    }
71}
72
73impl From<Primitive> for FunctionId {
74    fn from(op: Primitive) -> Self {
75        Self::Primitive(op)
76    }
77}
78
79impl fmt::Display for FunctionId {
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        match self {
82            FunctionId::Named(name) => write!(f, "{name}"),
83            FunctionId::Primitive(prim) => write!(f, "{prim}"),
84            FunctionId::Macro(Some(name), span) => write!(f, "macro expansion of {name} at {span}"),
85            FunctionId::Macro(None, span) => write!(f, "macro expansion of at {span}"),
86            FunctionId::Main => write!(f, "main"),
87            FunctionId::Unnamed => write!(f, "unnamed"),
88        }
89    }
90}