Skip to main content

csan_core/catalog/models/
cutter.rs

1//! Defines the generated Cutter number models.
2use derive_more::Display;
3use std::fmt;
4
5use crate::catalog::cutter::tables::CutterNumType;
6
7/// Represents a generated Library of Congress (`LoC`) Cutter number.
8///
9/// `LoC` Cutters always consist of a single initial alphabetic character
10/// followed by a numeric sequence derived from character-branching rules.
11///
12/// The `Display` implementation outputs the standard concatenated format
13/// (e.g. `C378` or `A153`).
14#[derive(Display)]
15#[display("{alpha_prefix}{numeric}")]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
17pub struct CutterLoc {
18    /// The initial letter of the cuttered name (e.g. `'C'`).
19    alpha_prefix: char,
20    /// The digit sequence derived from the `LoC` branching rules.
21    numeric: CutterNumType,
22}
23
24impl CutterLoc {
25    /// Creates a new `CutterLoc` instance.
26    ///
27    /// # Examples
28    /// ```
29    /// # use csan_core::catalog::models::cutter::CutterLoc;
30    ///
31    /// let loc_cutter = CutterLoc::new('C', 378);
32    /// assert_eq!(loc_cutter.to_string(), "C378");
33    /// ```
34    #[must_use]
35    pub fn new(alpha_prefix: char, numeric: CutterNumType) -> CutterLoc {
36        CutterLoc {
37            alpha_prefix,
38            numeric,
39        }
40    }
41
42    /// Returns the initial letter of the Cutter number.
43    #[must_use]
44    pub fn alpha_prefix(&self) -> char {
45        self.alpha_prefix
46    }
47
48    /// Returns the numeric portion of the Cutter number.
49    #[must_use]
50    pub fn numeric(&self) -> CutterNumType {
51        self.numeric
52    }
53}
54
55/// Represents a generated Cutter-Sanborn call number.
56///
57/// The `Display` implementation outputs the standard concatenated format
58/// with the optional lowercase work mark appended (e.g. `D548` or `D548o`).
59#[derive(Display)]
60#[display("{}{}{}", alpha_prefix, numeric, alpha_suffix.as_deref().unwrap_or(""))]
61#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
62pub struct CutterSanborn {
63    /// The alphabetic prefix taken from the author (or title) name,
64    /// e.g. `"D"` for Dickens.
65    alpha_prefix: String,
66    /// The number associated with the matched Cutter-Sanborn table entry.
67    numeric: CutterNumType,
68    /// The optional lowercase work mark derived from the title,
69    /// e.g. `"o"` for *Oliver Twist*.
70    alpha_suffix: Option<String>,
71    /// The Cutter-Sanborn table entry that was matched (e.g. `"Dickens"`).
72    entry: &'static str,
73}
74
75impl CutterSanborn {
76    /// Creates a new `CutterSanborn` instance from its parts.
77    #[must_use]
78    pub fn new(
79        alpha_prefix: String,
80        numeric: CutterNumType,
81        alpha_suffix: Option<String>,
82        entry: &'static str,
83    ) -> CutterSanborn {
84        CutterSanborn {
85            alpha_prefix,
86            numeric,
87            alpha_suffix,
88            entry,
89        }
90    }
91
92    /// Returns the alphabetic prefix of the call number.
93    #[must_use]
94    pub fn alpha_prefix(&self) -> &str {
95        &self.alpha_prefix
96    }
97
98    /// Returns the lowercase work mark, if one was generated.
99    #[must_use]
100    pub fn alpha_suffix(&self) -> Option<&str> {
101        self.alpha_suffix.as_deref()
102    }
103
104    /// Returns the numeric portion of the call number.
105    #[must_use]
106    pub fn numeric(&self) -> CutterNumType {
107        self.numeric
108    }
109
110    /// Returns the Cutter-Sanborn table entry that was matched.
111    #[must_use]
112    pub fn entry(&self) -> &'static str {
113        self.entry
114    }
115}
116
117/// Marker trait for the value types a
118/// [`CutterGenerator`](crate::catalog::cutter::CutterGenerator) can produce.
119///
120/// Every cutter model is displayable as its call number string.
121pub trait CutterType: fmt::Display {}
122impl CutterType for CutterSanborn {}
123impl CutterType for CutterLoc {}