nushell/crates/nu-protocol/src/signature.rs

190 lines
4.9 KiB
Rust
Raw Normal View History

use crate::syntax_shape::SyntaxShape;
2019-05-26 08:54:41 +02:00
use indexmap::IndexMap;
use nu_source::{b, DebugDocBuilder, PrettyDebug, PrettyDebugWithSource};
2019-07-02 09:56:20 +02:00
use serde::{Deserialize, Serialize};
2019-05-26 08:54:41 +02:00
2019-07-16 09:08:35 +02:00
#[derive(Debug, Serialize, Deserialize, Clone)]
2019-05-28 08:45:18 +02:00
pub enum NamedType {
Switch,
Mandatory(SyntaxShape),
Optional(SyntaxShape),
2019-05-26 08:54:41 +02:00
}
2019-07-02 09:56:20 +02:00
#[derive(Debug, Clone, Serialize, Deserialize)]
2019-05-28 08:45:18 +02:00
pub enum PositionalType {
Mandatory(String, SyntaxShape),
Optional(String, SyntaxShape),
2019-05-28 08:45:18 +02:00
}
impl PrettyDebug for PositionalType {
fn pretty(&self) -> DebugDocBuilder {
match self {
PositionalType::Mandatory(string, shape) => {
b::description(string) + b::delimit("(", shape.pretty(), ")").into_kind().group()
}
PositionalType::Optional(string, shape) => {
b::description(string)
+ b::operator("?")
+ b::delimit("(", shape.pretty(), ")").into_kind().group()
}
}
}
}
2019-05-28 08:45:18 +02:00
impl PositionalType {
pub fn mandatory(name: &str, ty: SyntaxShape) -> PositionalType {
2019-07-15 23:16:27 +02:00
PositionalType::Mandatory(name.to_string(), ty)
}
pub fn mandatory_any(name: &str) -> PositionalType {
PositionalType::Mandatory(name.to_string(), SyntaxShape::Any)
2019-07-13 04:07:06 +02:00
}
2019-07-16 21:10:25 +02:00
pub fn mandatory_block(name: &str) -> PositionalType {
PositionalType::Mandatory(name.to_string(), SyntaxShape::Block)
2019-07-16 21:10:25 +02:00
}
pub fn optional(name: &str, ty: SyntaxShape) -> PositionalType {
2019-07-16 09:25:48 +02:00
PositionalType::Optional(name.to_string(), ty)
}
pub fn optional_any(name: &str) -> PositionalType {
PositionalType::Optional(name.to_string(), SyntaxShape::Any)
2019-07-16 09:25:48 +02:00
}
pub fn name(&self) -> &str {
match self {
PositionalType::Mandatory(s, _) => s,
PositionalType::Optional(s, _) => s,
}
}
2019-07-15 23:16:27 +02:00
pub fn syntax_type(&self) -> SyntaxShape {
2019-07-15 23:16:27 +02:00
match *self {
PositionalType::Mandatory(_, t) => t,
PositionalType::Optional(_, t) => t,
}
}
2019-05-28 08:45:18 +02:00
}
2019-10-28 06:15:35 +01:00
type Description = String;
2019-11-18 04:12:37 +01:00
#[derive(Debug, Serialize, Deserialize, Clone)]
2019-08-02 21:15:07 +02:00
pub struct Signature {
2019-07-02 09:56:20 +02:00
pub name: String,
pub usage: String,
2019-10-28 06:15:35 +01:00
pub positional: Vec<(PositionalType, Description)>,
pub rest_positional: Option<(SyntaxShape, Description)>,
pub named: IndexMap<String, (NamedType, Description)>,
2019-07-02 09:56:20 +02:00
pub is_filter: bool,
2019-05-28 08:45:18 +02:00
}
impl PrettyDebugWithSource for Signature {
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
b::typed(
"signature",
b::description(&self.name)
+ b::preceded(
b::space(),
b::intersperse(
self.positional
.iter()
.map(|(ty, _)| ty.pretty_debug(source)),
b::space(),
),
),
)
}
}
2019-08-02 21:15:07 +02:00
impl Signature {
2019-11-18 04:12:37 +01:00
pub fn new(name: String) -> Signature {
Signature {
name,
usage: String::new(),
positional: vec![],
rest_positional: None,
named: IndexMap::new(),
is_filter: false,
}
}
2019-08-02 21:15:07 +02:00
pub fn build(name: impl Into<String>) -> Signature {
Signature::new(name.into())
2019-07-24 06:10:48 +02:00
}
pub fn desc(mut self, usage: impl Into<String>) -> Signature {
self.usage = usage.into();
self
}
2019-10-28 06:15:35 +01:00
pub fn required(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
self.positional.push((
PositionalType::Mandatory(name.into(), ty.into()),
desc.into(),
));
2019-07-24 06:10:48 +02:00
self
}
2019-10-28 06:15:35 +01:00
pub fn optional(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
self.positional.push((
PositionalType::Optional(name.into(), ty.into()),
desc.into(),
));
2019-07-24 06:10:48 +02:00
self
}
2019-10-28 06:15:35 +01:00
pub fn named(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
2019-08-02 21:15:07 +02:00
self.named
2019-10-28 06:15:35 +01:00
.insert(name.into(), (NamedType::Optional(ty.into()), desc.into()));
2019-08-02 21:15:07 +02:00
self
}
pub fn required_named(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
2019-10-28 06:15:35 +01:00
desc: impl Into<String>,
2019-08-02 21:15:07 +02:00
) -> Signature {
self.named
2019-10-28 06:15:35 +01:00
.insert(name.into(), (NamedType::Mandatory(ty.into()), desc.into()));
2019-08-02 21:15:07 +02:00
self
}
2019-10-28 06:15:35 +01:00
pub fn switch(mut self, name: impl Into<String>, desc: impl Into<String>) -> Signature {
self.named
.insert(name.into(), (NamedType::Switch, desc.into()));
2019-07-24 06:10:48 +02:00
self
}
2019-08-02 21:15:07 +02:00
pub fn filter(mut self) -> Signature {
self.is_filter = true;
self
}
2019-10-28 06:15:35 +01:00
pub fn rest(mut self, ty: SyntaxShape, desc: impl Into<String>) -> Signature {
self.rest_positional = Some((ty, desc.into()));
2019-08-02 21:15:07 +02:00
self
}
2019-07-24 06:10:48 +02:00
}