citum_schema_style/options/
titles.rs1#[cfg(feature = "schema")]
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16#[cfg_attr(feature = "schema", derive(JsonSchema))]
17#[serde(rename_all = "kebab-case")]
18pub enum TextCase {
19 Title,
21 Sentence,
23 SentenceApa,
26 SentenceNlm,
29 CapitalizeFirst,
31 Lowercase,
33 Uppercase,
35 AsIs,
37}
38
39#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
44#[cfg_attr(feature = "schema", derive(JsonSchema))]
45#[serde(untagged)]
46pub enum TitlesConfigEntry {
47 Preset(crate::presets::TitlePreset),
49 Explicit(Box<TitlesConfig>),
51}
52
53impl Default for TitlesConfigEntry {
54 fn default() -> Self {
55 TitlesConfigEntry::Explicit(Box::default())
56 }
57}
58
59impl TitlesConfigEntry {
60 pub fn resolve(&self) -> TitlesConfig {
62 match self {
63 TitlesConfigEntry::Preset(preset) => preset.config(),
64 TitlesConfigEntry::Explicit(config) => *config.clone(),
65 }
66 }
67}
68
69#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
71#[cfg_attr(feature = "schema", derive(JsonSchema))]
72#[serde(rename_all = "kebab-case")]
73pub struct TitlesConfig {
74 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
78 pub type_mapping: HashMap<String, String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub component: Option<TitleRendering>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub monograph: Option<TitleRendering>,
85 #[serde(skip_serializing_if = "Option::is_none")]
87 pub container_monograph: Option<TitleRendering>,
88 #[serde(skip_serializing_if = "Option::is_none")]
90 pub periodical: Option<TitleRendering>,
91 #[serde(skip_serializing_if = "Option::is_none")]
93 pub serial: Option<TitleRendering>,
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub default: Option<TitleRendering>,
97 #[serde(skip_serializing_if = "Option::is_none")]
99 pub custom: Option<HashMap<String, serde_json::Value>>,
100 #[serde(
104 flatten,
105 default,
106 skip_serializing_if = "std::collections::BTreeMap::is_empty"
107 )]
108 #[cfg_attr(feature = "schema", schemars(skip))]
109 pub unknown_fields: std::collections::BTreeMap<String, serde_yaml::Value>,
110}
111
112#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
114#[cfg_attr(feature = "schema", derive(JsonSchema))]
115#[serde(rename_all = "kebab-case")]
116pub struct TitleRendering {
117 #[serde(skip_serializing_if = "Option::is_none")]
119 pub text_case: Option<TextCase>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub emph: Option<bool>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub quote: Option<bool>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub strong: Option<bool>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub small_caps: Option<bool>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub prefix: Option<String>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub suffix: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub locale_overrides: Option<HashMap<String, TitleRendering>>,
134 #[serde(
138 flatten,
139 default,
140 skip_serializing_if = "std::collections::BTreeMap::is_empty"
141 )]
142 #[cfg_attr(feature = "schema", schemars(skip))]
143 pub unknown_fields: std::collections::BTreeMap<String, serde_yaml::Value>,
144}
145
146impl TitleRendering {
147 pub fn to_rendering(&self) -> crate::template::Rendering {
148 crate::template::Rendering {
149 text_case: self.text_case,
150 emph: self.emph,
151 quote: self.quote,
152 strong: self.strong,
153 small_caps: self.small_caps,
154 prefix: self.prefix.clone(),
155 suffix: self.suffix.clone(),
156 ..Default::default()
157 }
158 }
159
160 pub fn locale_override(&self, language: Option<&str>) -> Option<&TitleRendering> {
161 let overrides = self.locale_overrides.as_ref()?;
162 let language = language?;
163 overrides.get(language).or_else(|| {
164 language
165 .split('-')
166 .next()
167 .and_then(|tag| overrides.get(tag))
168 })
169 }
170}