Repository: nushell/nushell
File: crates/nu-parser/src/parse_shape_specs.rs (Rust)

Code before:
#![allow(clippy::byte_char_slices)]

use crate::{TokenContents, lex::lex_signature, parser::parse_value, trim_quotes};
use nu_protocol::{
    IntoSpanned, ParseError, Span, Spanned, SyntaxShape, Type, engine::StateWorkingSet,
};

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ShapeDescriptorUse {
    /// Used in an argument position allowing the addition of custom completion
    Argument,
    /// Used to define the type of a variable or input/output types
    Type,
}

/// equivalent to [`parse_shape_name`] with [`ShapeDescriptorUse::Type`] converting the
/// [`SyntaxShape`] to its [`Type`]
pub fn parse_type(working_set: &mut StateWorkingSet, bytes: &[u8], span: Span) -> Type {
    parse_shape_name(working_set, bytes, span, ShapeDescriptorUse::Type).to_type()
}

/// Parse the literals of [`Type`]-like [`SyntaxShape`]s including inner types.
/// Also handles the specification of custom completions with `type@completer`.
///
/// Restrict the parsing with `use_loc`
/// Used in:
/// - [`ShapeDescriptorUse::Argument`]
///   - `: ` argument type (+completer) positions in signatures
/// - [`ShapeDescriptorUse::Type`]
///   - `type->type` input/output type pairs
///   - `let name: type` variable type infos
///
/// NOTE: Does not provide a mapping to every [`SyntaxShape`]
pub fn parse_shape_name(
    working_set: &mut StateWorkingSet,
    bytes: &[u8],
    span: Span,
    use_loc: ShapeDescriptorUse,

Review comment (refactor):
I have  a slight emotioinal attachment to any enum like this making things clearer as to what is happening.

But removal seems reasonable when this is only used in `parse_signature_helper`

Code after:
#![allow(clippy::byte_char_slices)]

use crate::{TokenContents, lex::lex_signature, parser::parse_value, trim_quotes};
use nu_protocol::{
    DeclId, IntoSpanned, ParseError, Span, Spanned, SyntaxShape, Type, engine::StateWorkingSet,
};

/// [`parse_shape_name`] then convert to Type
pub fn parse_type(working_set: &mut StateWorkingSet, bytes: &[u8], span: Span) -> Type {
    parse_shape_name(working_set, bytes, span).to_type()
}

/// Parse the literals of [`Type`]-like [`SyntaxShape`]s including inner types.
///
/// NOTE: Does not provide a mapping to every [`SyntaxShape`]
pub fn parse_shape_name(
    working_set: &mut StateWorkingSet,
    bytes: &[u8],
    span: Span,
) -> SyntaxShape {
    match bytes {
        b"any" => SyntaxShape::Any,
        b"binary" => SyntaxShape::Binary,
        b"block" => {
            working_set.error(ParseError::LabeledErrorWithHelp {
                error: "Blocks are not support as first-class values".into(),
                label: "blocks are not supported as values".into(),
                help: "Use 'closure' instead of 'block'".into(),
                span,
            });
            SyntaxShape::Any
        }
        b"bool" => SyntaxShape::Boolean,
        b"cell-path" => SyntaxShape::CellPath,
        b"closure" => SyntaxShape::Closure(None), //FIXME: Blocks should have known output types
        b"datetime" => SyntaxShape::DateTime,
        b"directory" => SyntaxShape::Directory,
        b"duration" => SyntaxShape::Duration,