//! Module defining script-defined functions. #![cfg(not(feature = "no_function"))] use super::{FnAccess, StmtBlock}; use crate::{Identifier, Module, Shared, StaticVec}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{fmt, hash::Hash}; /// _(internals)_ A type containing information on a script-defined function. /// Exported under the `internals` feature only. #[derive(Debug, Clone)] pub struct ScriptFnDef { /// Function body. pub body: StmtBlock, /// Encapsulated running environment, if any. pub lib: Option>, /// Encapsulated stack of imported modules, if any. /// /// Not available under `no_module`. #[cfg(not(feature = "no_module"))] pub global: Option)]>>, /// Function name. pub name: Identifier, /// Function access mode. pub access: FnAccess, /// Names of function parameters. pub params: StaticVec, /// _(metadata)_ Function doc-comments (if any). /// Exported under the `metadata` feature only. #[cfg(feature = "metadata")] pub comments: Option]>>, } impl fmt::Display for ScriptFnDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}{}({})", match self.access { FnAccess::Public => "", FnAccess::Private => "private ", }, self.name, self.params .iter() .map(|s| s.as_str()) .collect::>() .join(", ") ) } } /// A type containing the metadata of a script-defined function. /// /// Not available under `no_function`. /// /// Created by [`AST::iter_functions`][super::AST::iter_functions]. #[derive(Debug, Eq, PartialEq, Clone, Hash)] pub struct ScriptFnMetadata<'a> { /// _(metadata)_ Function doc-comments (if any). /// Exported under the `metadata` feature only. /// /// Block doc-comments are kept in a single string slice with line-breaks within. /// /// Line doc-comments are kept in one string slice per line without the termination line-break. /// /// Leading white-spaces are stripped, and each string slice always starts with the corresponding /// doc-comment leader: `///` or `/**`. #[cfg(feature = "metadata")] pub comments: Vec<&'a str>, /// Function access mode. pub access: FnAccess, /// Function name. pub name: &'a str, /// Function parameters (if any). pub params: Vec<&'a str>, } impl fmt::Display for ScriptFnMetadata<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}{}({})", match self.access { FnAccess::Public => "", FnAccess::Private => "private ", }, self.name, self.params .iter() .cloned() .collect::>() .join(", ") ) } } impl<'a> From<&'a ScriptFnDef> for ScriptFnMetadata<'a> { #[inline] fn from(value: &'a ScriptFnDef) -> Self { Self { #[cfg(feature = "metadata")] comments: value .comments .as_ref() .map_or_else(|| Vec::new(), |v| v.iter().map(Box::as_ref).collect()), access: value.access, name: &value.name, params: value.params.iter().map(|s| s.as_str()).collect(), } } } impl std::cmp::PartialOrd for ScriptFnMetadata<'_> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl std::cmp::Ord for ScriptFnMetadata<'_> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { match self.name.cmp(other.name) { std::cmp::Ordering::Equal => self.params.len().cmp(&other.params.len()), cmp => cmp, } } }