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)]
361#[non_exhaustive]
362pub enum RefContentType {
363 #[default]
365 Page,
366 Number,
370 Contents,
379 UpDownPos,
381 Unknown(u8),
384}
385
386impl fmt::Display for RefContentType {
387 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388 match self {
389 Self::Page => f.write_str("OBJECT_TYPE_PAGE"),
390 Self::Number => f.write_str("OBJECT_TYPE_NUMBER"),
391 Self::Contents => f.write_str("OBJECT_TYPE_CONTENTS"),
396 Self::UpDownPos => f.write_str("OBJECT_TYPE_UPDOWNPOS"),
397 Self::Unknown(code) => write!(f, "OBJECT_TYPE_UNKNOWN({code})"),
398 }
399 }
400}
401
402impl std::str::FromStr for RefContentType {
403 type Err = FoundationError;
404
405 fn from_str(s: &str) -> Result<Self, Self::Err> {
406 match s {
407 "OBJECT_TYPE_PAGE" | "Page" | "page" => Ok(Self::Page),
408 "OBJECT_TYPE_NUMBER" | "Number" | "number" => Ok(Self::Number),
409 "OBJECT_TYPE_CONTENTS" | "Contents" | "contents" => Ok(Self::Contents),
413 "OBJECT_TYPE_UPDOWNPOS" | "UpDownPos" | "updownpos" => Ok(Self::UpDownPos),
414 _ => Err(FoundationError::ParseError {
415 type_name: "RefContentType".to_string(),
416 value: s.to_string(),
417 valid_values: "OBJECT_TYPE_PAGE, OBJECT_TYPE_NUMBER, OBJECT_TYPE_CONTENTS, \
418 OBJECT_TYPE_UPDOWNPOS"
419 .to_string(),
420 }),
421 }
422 }
423}
424
425impl schemars::JsonSchema for RefContentType {
426 fn schema_name() -> std::borrow::Cow<'static, str> {
427 std::borrow::Cow::Borrowed("RefContentType")
428 }
429
430 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
431 gen.subschema_for::<String>()
432 }
433}
434
435#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
449#[non_exhaustive]
450pub enum DropCapStyle {
451 #[default]
453 None = 0,
454 DoubleLine = 1,
456 TripleLine = 2,
458 Margin = 3,
460}
461
462impl fmt::Display for DropCapStyle {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 match self {
465 Self::None => f.write_str("None"),
466 Self::DoubleLine => f.write_str("DoubleLine"),
467 Self::TripleLine => f.write_str("TripleLine"),
468 Self::Margin => f.write_str("Margin"),
469 }
470 }
471}
472
473impl DropCapStyle {
474 pub fn from_hwpx_str(s: &str) -> Self {
478 match s {
479 "DoubleLine" => Self::DoubleLine,
480 "TripleLine" => Self::TripleLine,
481 "Margin" => Self::Margin,
482 _ => Self::None,
483 }
484 }
485}
486
487impl std::str::FromStr for DropCapStyle {
488 type Err = FoundationError;
489
490 fn from_str(s: &str) -> Result<Self, Self::Err> {
491 match s {
492 "None" | "NONE" | "none" => Ok(Self::None),
493 "DoubleLine" | "DOUBLE_LINE" => Ok(Self::DoubleLine),
494 "TripleLine" | "TRIPLE_LINE" => Ok(Self::TripleLine),
495 "Margin" | "MARGIN" => Ok(Self::Margin),
496 _ => Err(FoundationError::ParseError {
497 type_name: "DropCapStyle".to_string(),
498 value: s.to_string(),
499 valid_values: "None, DoubleLine, TripleLine, Margin".to_string(),
500 }),
501 }
502 }
503}
504
505impl schemars::JsonSchema for DropCapStyle {
506 fn schema_name() -> std::borrow::Cow<'static, str> {
507 std::borrow::Cow::Borrowed("DropCapStyle")
508 }
509
510 fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
511 gen.subschema_for::<String>()
512 }
513}
514
515impl serde::Serialize for DropCapStyle {
516 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
517 serializer.serialize_str(&self.to_string())
518 }
519}
520
521impl<'de> serde::Deserialize<'de> for DropCapStyle {
522 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
523 let s = String::deserialize(deserializer)?;
524 s.parse().map_err(serde::de::Error::custom)
525 }
526}