citum_schema_data/reference/
date.rs1use crate::reference::types::RefDate;
7#[cfg(feature = "schema")]
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use std::fmt;
11
12#[derive(Debug, Deserialize, Serialize, Clone, Default, PartialEq)]
14#[cfg_attr(feature = "schema", derive(JsonSchema))]
15#[cfg_attr(feature = "bindings", derive(specta::Type))]
16pub struct EdtfString(pub String);
17
18impl EdtfString {
19 pub fn is_empty(&self) -> bool {
21 self.0.is_empty()
22 }
23
24 pub fn parse(&self) -> RefDate {
26 let mut input = self.0.as_str();
27 match citum_edtf::parse(&mut input) {
28 Ok(edtf) => RefDate::Edtf(edtf),
29 Err(_) => RefDate::Literal(self.0.clone()),
30 }
31 }
32
33 pub fn year(&self) -> String {
35 match self.parse() {
36 RefDate::Edtf(edtf) => edtf.year().to_string(),
37 RefDate::Literal(_) => String::new(),
38 }
39 }
40
41 pub fn day(&self) -> Option<u32> {
43 match self.parse() {
44 RefDate::Edtf(edtf) => edtf.day().filter(|&d| d > 0),
45 RefDate::Literal(_) => None,
46 }
47 }
48
49 pub fn is_uncertain(&self) -> bool {
51 self.0.contains('?')
52 }
53
54 pub fn is_approximate(&self) -> bool {
56 self.0.contains('~')
57 }
58
59 pub fn is_range(&self) -> bool {
61 matches!(self.parse(), RefDate::Edtf(edtf) if edtf.is_range())
62 }
63
64 pub fn is_open_range(&self) -> bool {
66 matches!(self.parse(), RefDate::Edtf(edtf) if edtf.is_open_range())
67 }
68
69 pub fn time(&self) -> Option<citum_edtf::Time> {
71 match self.parse() {
72 RefDate::Edtf(edtf) => edtf.time(),
73 _ => None,
74 }
75 }
76
77 pub fn has_time(&self) -> bool {
79 self.time().is_some()
80 }
81}
82
83impl fmt::Display for EdtfString {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 write!(f, "{}", self.0)
86 }
87}