slicec 0.4.0

The Slice parser and other core components for Slice compilers.
Documentation
// Copyright (c) ZeroC, Inc.

use super::super::*;

#[derive(Debug, Eq, PartialEq)]
pub enum Primitive {
    Bool,
    Int8,
    UInt8,
    Int16,
    UInt16,
    Int32,
    UInt32,
    VarInt32,
    VarUInt32,
    Int64,
    UInt64,
    VarInt62,
    VarUInt62,
    Float32,
    Float64,
    String,
}

impl Primitive {
    pub fn is_integral(&self) -> bool {
        matches!(
            self,
            Self::Int8
                | Self::UInt8
                | Self::Int16
                | Self::UInt16
                | Self::Int32
                | Self::UInt32
                | Self::VarInt32
                | Self::VarUInt32
                | Self::Int64
                | Self::UInt64
                | Self::VarInt62
                | Self::VarUInt62
        )
    }

    pub fn numeric_bounds(&self) -> Option<(i128, i128)> {
        const VARINT62_MIN: i128 = -2_305_843_009_213_693_952; // -2^61
        const VARINT62_MAX: i128 = 2_305_843_009_213_693_951; // 2^61 - 1
        const VARUINT62_MAX: i128 = 4_611_686_018_427_387_903; // 2^62 - 1

        match self {
            Self::Int8 => Some((i8::MIN as i128, i8::MAX as i128)),
            Self::UInt8 => Some((0, u8::MAX as i128)),
            Self::Int16 => Some((i16::MIN as i128, i16::MAX as i128)),
            Self::UInt16 => Some((0, u16::MAX as i128)),
            Self::Int32 => Some((i32::MIN as i128, i32::MAX as i128)),
            Self::UInt32 => Some((0, u32::MAX as i128)),
            Self::VarInt32 => Some((i32::MIN as i128, i32::MAX as i128)),
            Self::VarUInt32 => Some((0, u32::MAX as i128)),
            Self::Int64 => Some((i64::MIN as i128, i64::MAX as i128)),
            Self::UInt64 => Some((0, u64::MAX as i128)),
            Self::VarInt62 => Some((VARINT62_MIN, VARINT62_MAX)),
            Self::VarUInt62 => Some((0, VARUINT62_MAX)),
            _ => None,
        }
    }
}

impl Type for Primitive {
    fn type_string(&self) -> String {
        self.kind().to_owned()
    }
}

impl Element for Primitive {
    fn kind(&self) -> &'static str {
        match self {
            Self::Bool => "bool",
            Self::Int8 => "int8",
            Self::UInt8 => "uint8",
            Self::Int16 => "int16",
            Self::UInt16 => "uint16",
            Self::Int32 => "int32",
            Self::UInt32 => "uint32",
            Self::VarInt32 => "varint32",
            Self::VarUInt32 => "varuint32",
            Self::Int64 => "int64",
            Self::UInt64 => "uint64",
            Self::VarInt62 => "varint62",
            Self::VarUInt62 => "varuint62",
            Self::Float32 => "float32",
            Self::Float64 => "float64",
            Self::String => "string",
        }
    }
}