clauser/
types.rs

1use std::borrow::Cow;
2
3#[cfg(feature = "serde")]
4use serde::Deserialize;
5
6use zerocopy::transmute;
7use zerocopy_derive::{AsBytes, FromBytes, FromZeroes};
8
9use crate::token::TokenType;
10
11/// Types that are actually differentiable purely from tokens.
12#[derive(Debug, Eq, PartialEq)]
13pub enum RealType {
14    /// An object or an array.
15    ///
16    /// While *most* objects or arrays can be differentiated, a string of
17    /// `{}` could be either one - so we have to admit we don't know.
18    ObjectOrArray,
19    /// An integer or decimal number.
20    Number,
21    /// A boolean "yes" or "no" value.
22    Boolean,
23    /// A string.
24    String,
25    /// An identifier.
26    Identifier,
27    /// A date.
28    Date,
29}
30
31/// The possible kinds of collections in a Clausewitz file.
32#[derive(Debug, Eq, PartialEq)]
33pub enum CollectionType {
34    /// A key-value map.
35    Object,
36    /// A sequence of values.
37    Array,
38}
39
40impl RealType {
41    /// Creates a [RealType] from a [TokenType], if possible.
42    ///
43    /// Not all [TokenType] values have equivalent [RealType] values.
44    pub fn from_token_type(t: &TokenType) -> Option<RealType> {
45        match *t {
46            TokenType::Boolean => Some(RealType::Boolean),
47            TokenType::Number => Some(RealType::Number),
48            TokenType::Identifier => Some(RealType::Identifier),
49            TokenType::String => Some(RealType::String),
50            TokenType::OpenBracket => Some(RealType::ObjectOrArray),
51            TokenType::Date => Some(RealType::Date),
52            _ => None,
53        }
54    }
55}
56
57/// A value specifying years, months, days, and possibly hours.
58#[derive(
59    Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, FromZeroes, FromBytes, AsBytes, Hash,
60)]
61#[repr(C)]
62#[cfg_attr(feature = "serde", derive(Deserialize), serde(from = "u128"))]
63pub struct Date {
64    /// The number of years in this date.
65    pub years: u32,
66    /// The number of months in this date.
67    pub months: u32,
68    /// The number of days in this date.
69    pub days: u32,
70    /// The number of hours in this date.
71    /// If the source value had no hours component, this will be 0.
72    pub hours: u32,
73}
74
75impl Date {
76    /// Creates a new [Date] from the given years, months, days, and hours values.
77    pub fn new(years: u32, months: u32, days: u32, hours: u32) -> Date {
78        Date {
79            years,
80            months,
81            days,
82            hours,
83        }
84    }
85}
86
87impl From<[u32; 4]> for Date {
88    fn from(value: [u32; 4]) -> Self {
89        Date {
90            years: value[0],
91            months: value[1],
92            days: value[2],
93            hours: value[3],
94        }
95    }
96}
97
98impl From<Date> for [u32; 4] {
99    fn from(value: Date) -> Self {
100        [value.years, value.months, value.days, value.hours]
101    }
102}
103
104impl From<u128> for Date {
105    fn from(value: u128) -> Self {
106        let parts: [u32; 4] = transmute!(value);
107
108        parts.into()
109    }
110}
111
112impl From<Date> for u128 {
113    fn from(value: Date) -> Self {
114        let indices: [u32; 4] = [value.years, value.months, value.days, value.hours];
115        transmute!(indices)
116    }
117}
118
119impl From<Date> for (u32, u32, u32, u32) {
120    fn from(value: Date) -> Self {
121        (value.years, value.months, value.days, value.hours)
122    }
123}
124
125/// Represents the key of an object in a [Value](`crate::value::Value`).
126#[derive(Debug, PartialEq, PartialOrd, Clone)]
127pub enum ObjectKey<'src> {
128    /// An Identifier key
129    Identifier(Cow<'src, str>),
130    /// A Date key
131    Date(Date),
132}
133
134impl<'src> From<Date> for ObjectKey<'src> {
135    fn from(value: Date) -> Self {
136        ObjectKey::Date(value)
137    }
138}
139
140impl<'src> From<&'src str> for ObjectKey<'src> {
141    fn from(value: &'src str) -> Self {
142        ObjectKey::Identifier(value.into())
143    }
144}
145
146impl<'src> From<String> for ObjectKey<'src> {
147    fn from(value: String) -> Self {
148        ObjectKey::Identifier(value.into())
149    }
150}