Skip to main content

jumpcut/pagination/
fixtures.rs

1use crate::render_attributes::RenderAttributes;
2use crate::styled_text::StyledText;
3use serde::{Deserialize, Deserializer, Serialize};
4
5#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "kebab-case")]
7pub enum Fragment {
8    Whole,
9    ContinuedFromPrev,
10    ContinuedToNext,
11    ContinuedFromPrevAndToNext,
12}
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
15pub struct LineRange(pub u32, pub u32);
16
17#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
18pub struct PaginationScope {
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub first_page_number: Option<u32>,
21    pub title_page_count: Option<u32>,
22    pub body_start_page: Option<u32>,
23}
24
25#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
26pub struct PageBreakFixtureSourceRefs {
27    pub fountain: Option<String>,
28    pub fdx: Option<String>,
29    pub pdf: Option<String>,
30}
31
32#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
33pub struct NormalizedElement {
34    pub element_id: String,
35    pub kind: String,
36    pub text: String,
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub inline_text: Option<StyledText>,
39    #[serde(default, skip_serializing_if = "RenderAttributes::is_default")]
40    pub render_attributes: RenderAttributes,
41    pub fragment: Option<Fragment>,
42    pub block_kind: Option<String>,
43    pub block_id: Option<String>,
44    pub dual_dialogue_group: Option<String>,
45    pub dual_dialogue_side: Option<u8>,
46}
47
48impl<'de> Deserialize<'de> for NormalizedElement {
49    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50    where
51        D: Deserializer<'de>,
52    {
53        #[derive(Deserialize)]
54        struct NormalizedElementRepr {
55            element_id: String,
56            kind: String,
57            text: String,
58            #[serde(default)]
59            inline_text: Option<StyledText>,
60            #[serde(default)]
61            render_attributes: Option<RenderAttributes>,
62            fragment: Option<Fragment>,
63            #[serde(default)]
64            centered: bool,
65            #[serde(default)]
66            starts_new_page: bool,
67            #[serde(default)]
68            scene_number: Option<String>,
69            block_kind: Option<String>,
70            block_id: Option<String>,
71            dual_dialogue_group: Option<String>,
72            dual_dialogue_side: Option<u8>,
73        }
74
75        let repr = NormalizedElementRepr::deserialize(deserializer)?;
76        let render_attributes = repr.render_attributes.unwrap_or(RenderAttributes {
77            centered: repr.centered,
78            starts_new_page: repr.starts_new_page,
79            scene_number: repr.scene_number,
80            ..RenderAttributes::default()
81        });
82
83        Ok(Self {
84            element_id: repr.element_id,
85            kind: repr.kind,
86            text: repr.text,
87            inline_text: repr.inline_text,
88            render_attributes,
89            fragment: repr.fragment,
90            block_kind: repr.block_kind,
91            block_id: repr.block_id,
92            dual_dialogue_group: repr.dual_dialogue_group,
93            dual_dialogue_side: repr.dual_dialogue_side,
94        })
95    }
96}
97
98#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
99pub struct NormalizedScreenplay {
100    pub screenplay: String,
101    pub starting_page_number: Option<u32>,
102    pub elements: Vec<NormalizedElement>,
103}
104
105#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
106pub struct PageItem {
107    pub element_id: String,
108    pub kind: String,
109    #[serde(default, skip_serializing_if = "Option::is_none")]
110    pub text_preview: Option<String>,
111    pub fragment: Fragment,
112    pub line_range: Option<LineRange>,
113    pub block_id: Option<String>,
114    pub dual_dialogue_group: Option<String>,
115    pub dual_dialogue_side: Option<u8>,
116}
117
118#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
119pub struct PageBreakFixturePage {
120    pub number: u32,
121    pub items: Vec<PageItem>,
122}
123
124#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
125pub struct PageBreakFixture {
126    pub screenplay: String,
127    pub style_profile: String,
128    pub source: PageBreakFixtureSourceRefs,
129    pub scope: PaginationScope,
130    pub pages: Vec<PageBreakFixturePage>,
131}