1use crate::error::FoundationError;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
16#[non_exhaustive]
17#[repr(u8)]
18pub enum BookmarkType {
19 #[default]
21 Point = 0,
22 SpanStart = 1,
24 SpanEnd = 2,
26}
27
28impl fmt::Display for BookmarkType {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Point => f.write_str("Point"),
32 Self::SpanStart => f.write_str("SpanStart"),
33 Self::SpanEnd => f.write_str("SpanEnd"),
34 }
35 }
36}
37
38impl std::str::FromStr for BookmarkType {
39 type Err = FoundationError;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 match s {
43 "Point" | "point" => Ok(Self::Point),
44 "SpanStart" | "span_start" => Ok(Self::SpanStart),
45 "SpanEnd" | "span_end" => Ok(Self::SpanEnd),
46 _ => Err(FoundationError::ParseError {
47 type_name: "BookmarkType".to_string(),
48 value: s.to_string(),
49 valid_values: "Point, SpanStart, SpanEnd".to_string(),
50 }),
51 }
52 }
53}
54
55impl TryFrom<u8> for BookmarkType {
56 type Error = FoundationError;
57
58 fn try_from(value: u8) -> Result<Self, Self::Error> {
59 match value {
60 0 => Ok(Self::Point),
61 1 => Ok(Self::SpanStart),
62 2 => Ok(Self::SpanEnd),
63 _ => Err(FoundationError::ParseError {
64 type_name: "BookmarkType".to_string(),
65 value: value.to_string(),
66 valid_values: "0 (Point), 1 (SpanStart), 2 (SpanEnd)".to_string(),
67 }),
68 }
69 }
70}
71
72impl schemars::JsonSchema for BookmarkType {
73 fn schema_name() -> std::borrow::Cow<'static, str> {
74 std::borrow::Cow::Borrowed("BookmarkType")
75 }
76
77 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
78 gen.subschema_for::<String>()
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
98#[non_exhaustive]
99#[repr(u8)]
100pub enum FieldType {
101 #[default]
103 ClickHere = 0,
104 Author = 1,
106 LastSavedBy = 2,
108 CreatedTime = 3,
110 ModifiedTime = 4,
112 Title = 5,
114}
115
116impl FieldType {
117 #[must_use]
120 pub fn summary_token(self) -> Option<&'static str> {
121 match self {
122 Self::ClickHere => None,
123 Self::Author => Some("$author"),
124 Self::LastSavedBy => Some("$lastsaveby"),
125 Self::CreatedTime => Some("$createtime"),
126 Self::ModifiedTime => Some("$modifiedtime"),
127 Self::Title => Some("$title"),
128 }
129 }
130
131 #[must_use]
135 pub fn from_summary_token(token: &str) -> Option<Self> {
136 match token {
137 "$author" => Some(Self::Author),
138 "$lastsaveby" => Some(Self::LastSavedBy),
139 "$createtime" => Some(Self::CreatedTime),
140 "$modifiedtime" => Some(Self::ModifiedTime),
141 "$title" => Some(Self::Title),
142 _ => None,
143 }
144 }
145
146 #[must_use]
161 pub fn hwpx_editable(self) -> bool {
162 match self {
163 Self::ClickHere => true,
164 Self::Author | Self::Title => false,
165 Self::LastSavedBy | Self::CreatedTime | Self::ModifiedTime => true,
166 }
167 }
168}
169
170impl fmt::Display for FieldType {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 match self {
173 Self::ClickHere => f.write_str("CLICK_HERE"),
174 Self::Author => f.write_str("AUTHOR"),
175 Self::LastSavedBy => f.write_str("LAST_SAVED_BY"),
176 Self::CreatedTime => f.write_str("CREATED_TIME"),
177 Self::ModifiedTime => f.write_str("MODIFIED_TIME"),
178 Self::Title => f.write_str("TITLE"),
179 }
180 }
181}
182
183impl std::str::FromStr for FieldType {
184 type Err = FoundationError;
185
186 fn from_str(s: &str) -> Result<Self, Self::Err> {
187 match s {
188 "CLICK_HERE" | "ClickHere" | "click_here" => Ok(Self::ClickHere),
189 "AUTHOR" | "Author" | "author"
190 | "DOC_SUMMARY" | "DocSummary" | "doc_summary" => Ok(Self::Author),
192 "LAST_SAVED_BY" | "LastSavedBy" | "last_saved_by"
193 | "USER_INFO" | "UserInfo" | "user_info" => Ok(Self::LastSavedBy),
195 "CREATED_TIME" | "CreatedTime" | "created_time"
196 | "TIME" | "Time" | "time" => Ok(Self::CreatedTime),
198 "MODIFIED_TIME" | "ModifiedTime" | "modified_time"
199 | "DATE" | "Date" | "date" => Ok(Self::ModifiedTime),
201 "TITLE" | "Title" | "title" => Ok(Self::Title),
202 _ => Err(FoundationError::ParseError {
203 type_name: "FieldType".to_string(),
204 value: s.to_string(),
205 valid_values:
206 "CLICK_HERE, AUTHOR, LAST_SAVED_BY, CREATED_TIME, MODIFIED_TIME, TITLE"
207 .to_string(),
208 }),
209 }
210 }
211}
212
213impl TryFrom<u8> for FieldType {
214 type Error = FoundationError;
215
216 fn try_from(value: u8) -> Result<Self, Self::Error> {
217 match value {
218 0 => Ok(Self::ClickHere),
219 1 => Ok(Self::Author),
220 2 => Ok(Self::LastSavedBy),
221 3 => Ok(Self::CreatedTime),
222 4 => Ok(Self::ModifiedTime),
223 5 => Ok(Self::Title),
224 _ => Err(FoundationError::ParseError {
225 type_name: "FieldType".to_string(),
226 value: value.to_string(),
227 valid_values: "0..5 (ClickHere..Title)".to_string(),
228 }),
229 }
230 }
231}
232
233impl schemars::JsonSchema for FieldType {
234 fn schema_name() -> std::borrow::Cow<'static, str> {
235 std::borrow::Cow::Borrowed("FieldType")
236 }
237
238 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
239 gen.subschema_for::<String>()
240 }
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
258#[non_exhaustive]
259pub enum RefType {
260 #[default]
262 Bookmark,
263 Table,
265 Figure,
267 Equation,
269 Footnote,
271 Endnote,
273 Outline,
275 Unknown(u8),
280}
281
282impl fmt::Display for RefType {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 match self {
285 Self::Bookmark => f.write_str("TARGET_BOOKMARK"),
286 Self::Table => f.write_str("TARGET_TABLE"),
287 Self::Figure => f.write_str("TARGET_FIGURE"),
288 Self::Equation => f.write_str("TARGET_EQUATION"),
289 Self::Footnote => f.write_str("TARGET_FOOTNOTE"),
290 Self::Endnote => f.write_str("TARGET_ENDNOTE"),
291 Self::Outline => f.write_str("TARGET_OUTLINE"),
292 Self::Unknown(code) => write!(f, "TARGET_UNKNOWN({code})"),
293 }
294 }
295}
296
297impl std::str::FromStr for RefType {
298 type Err = FoundationError;
299
300 fn from_str(s: &str) -> Result<Self, Self::Err> {
301 match s {
302 "TARGET_BOOKMARK" | "Bookmark" | "bookmark" => Ok(Self::Bookmark),
303 "TARGET_TABLE" | "Table" | "table" => Ok(Self::Table),
304 "TARGET_FIGURE" | "Figure" | "figure" => Ok(Self::Figure),
305 "TARGET_EQUATION" | "Equation" | "equation" => Ok(Self::Equation),
306 "TARGET_FOOTNOTE" | "Footnote" | "footnote" => Ok(Self::Footnote),
307 "TARGET_ENDNOTE" | "Endnote" | "endnote" => Ok(Self::Endnote),
308 "TARGET_OUTLINE" | "Outline" | "outline" => Ok(Self::Outline),
309 _ => Err(FoundationError::ParseError {
310 type_name: "RefType".to_string(),
311 value: s.to_string(),
312 valid_values: "TARGET_BOOKMARK, TARGET_TABLE, TARGET_FIGURE, TARGET_EQUATION, \
313 TARGET_FOOTNOTE, TARGET_ENDNOTE, TARGET_OUTLINE"
314 .to_string(),
315 }),
316 }
317 }
318}
319
320impl schemars::JsonSchema for RefType {
321 fn schema_name() -> std::borrow::Cow<'static, str> {
322 std::borrow::Cow::Borrowed("RefType")
323 }
324
325 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
326 gen.subschema_for::<String>()
327 }
328}
329
330#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
358#[non_exhaustive]
359pub enum RefContentType {
360 #[default]
362 Page,
363 Number,
367 Contents,
373 BookmarkName,
377 UpDownPos,
379 Unknown(u8),
382}
383
384impl fmt::Display for RefContentType {
385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386 match self {
387 Self::Page => f.write_str("OBJECT_TYPE_PAGE"),
388 Self::Number => f.write_str("OBJECT_TYPE_NUMBER"),
389 Self::Contents | Self::BookmarkName => f.write_str("OBJECT_TYPE_CONTENTS"),
394 Self::UpDownPos => f.write_str("OBJECT_TYPE_UPDOWNPOS"),
395 Self::Unknown(code) => write!(f, "OBJECT_TYPE_UNKNOWN({code})"),
396 }
397 }
398}
399
400impl std::str::FromStr for RefContentType {
401 type Err = FoundationError;
402
403 fn from_str(s: &str) -> Result<Self, Self::Err> {
404 match s {
405 "OBJECT_TYPE_PAGE" | "Page" | "page" => Ok(Self::Page),
406 "OBJECT_TYPE_NUMBER" | "Number" | "number" => Ok(Self::Number),
407 "OBJECT_TYPE_CONTENTS" | "Contents" | "contents" => Ok(Self::Contents),
413 "BookmarkName" | "bookmark_name" => Ok(Self::BookmarkName),
414 "OBJECT_TYPE_UPDOWNPOS" | "UpDownPos" | "updownpos" => Ok(Self::UpDownPos),
415 _ => Err(FoundationError::ParseError {
416 type_name: "RefContentType".to_string(),
417 value: s.to_string(),
418 valid_values: "OBJECT_TYPE_PAGE, OBJECT_TYPE_NUMBER, OBJECT_TYPE_CONTENTS, \
419 OBJECT_TYPE_UPDOWNPOS"
420 .to_string(),
421 }),
422 }
423 }
424}
425
426impl schemars::JsonSchema for RefContentType {
427 fn schema_name() -> std::borrow::Cow<'static, str> {
428 std::borrow::Cow::Borrowed("RefContentType")
429 }
430
431 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
432 gen.subschema_for::<String>()
433 }
434}
435
436#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
450#[non_exhaustive]
451pub enum DropCapStyle {
452 #[default]
454 None = 0,
455 DoubleLine = 1,
457 TripleLine = 2,
459 Margin = 3,
461}
462
463impl fmt::Display for DropCapStyle {
464 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
465 match self {
466 Self::None => f.write_str("None"),
467 Self::DoubleLine => f.write_str("DoubleLine"),
468 Self::TripleLine => f.write_str("TripleLine"),
469 Self::Margin => f.write_str("Margin"),
470 }
471 }
472}
473
474impl DropCapStyle {
475 pub fn from_hwpx_str(s: &str) -> Self {
479 match s {
480 "DoubleLine" => Self::DoubleLine,
481 "TripleLine" => Self::TripleLine,
482 "Margin" => Self::Margin,
483 _ => Self::None,
484 }
485 }
486}
487
488impl std::str::FromStr for DropCapStyle {
489 type Err = FoundationError;
490
491 fn from_str(s: &str) -> Result<Self, Self::Err> {
492 match s {
493 "None" | "NONE" | "none" => Ok(Self::None),
494 "DoubleLine" | "DOUBLE_LINE" => Ok(Self::DoubleLine),
495 "TripleLine" | "TRIPLE_LINE" => Ok(Self::TripleLine),
496 "Margin" | "MARGIN" => Ok(Self::Margin),
497 _ => Err(FoundationError::ParseError {
498 type_name: "DropCapStyle".to_string(),
499 value: s.to_string(),
500 valid_values: "None, DoubleLine, TripleLine, Margin".to_string(),
501 }),
502 }
503 }
504}
505
506impl schemars::JsonSchema for DropCapStyle {
507 fn schema_name() -> std::borrow::Cow<'static, str> {
508 std::borrow::Cow::Borrowed("DropCapStyle")
509 }
510
511 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
512 gen.subschema_for::<String>()
513 }
514}
515
516impl serde::Serialize for DropCapStyle {
517 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
518 serializer.serialize_str(&self.to_string())
519 }
520}
521
522impl<'de> serde::Deserialize<'de> for DropCapStyle {
523 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
524 let s = String::deserialize(deserializer)?;
525 s.parse().map_err(serde::de::Error::custom)
526 }
527}