1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use serde::{Deserialize, Serialize};
use crate::presentation::{AnnotationPage, LangMap, Metadata, Resource};
/// Canvas 结构:定义一个时间/空间上的呈现平面。
///
/// Canvas structure: defines the spatial/temporal plane for rendering content.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Canvas {
pub id: String,
#[serde(default = "canvas_type")]
pub r#type: String,
/// 画布标题。
///
/// Human-readable label of the canvas.
pub label: LangMap,
/// 画布的简要摘要(可多语言)。
///
/// Short summary/description of the canvas (multi-language).
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<LangMap>,
/// 画布的元数据条目列表。
///
/// Metadata entries for the canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Vec<Metadata>>,
/// 画布的必需声明(如版权信息)。
///
/// Required statement for the canvas (e.g. copyright).
#[serde(skip_serializing_if = "Option::is_none")]
pub required_statement: Option<Metadata>,
/// 权利或许可 URI。
///
/// Rights or license URI.
#[serde(skip_serializing_if = "Option::is_none")]
pub rights: Option<String>,
/// 画布使用的语言代码列表。
///
/// List of language codes used in this canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub height: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<f64>,
/// 查看方向(如 left-to-right、right-to-left 等)。
///
/// Viewing direction (e.g. left-to-right, right-to-left, etc.).
#[serde(skip_serializing_if = "Option::is_none")]
pub viewing_direction: Option<String>,
/// 行为提示(如 `paged`、`continuous`)。
///
/// Behavioral hints for the canvas (e.g. `paged`, `continuous`).
#[serde(skip_serializing_if = "Option::is_none")]
pub behavior: Option<Vec<String>>,
/// 画布的缩略图资源。
///
/// Thumbnail resources for the canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail: Option<Vec<Resource>>,
/// 画布的主页资源。
///
/// Homepage resources for the canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub homepage: Option<Vec<Resource>>,
/// 相关的外部机器可读资源。
///
/// Machine-readable external resources related to this canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub see_also: Option<Vec<Resource>>,
/// 画布的其他渲染形式。
///
/// Alternative renderings of this canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub rendering: Option<Vec<Resource>>,
/// 与该画布相关的服务。
///
/// Services related to this canvas.
#[serde(skip_serializing_if = "Option::is_none")]
pub service: Option<Vec<Resource>>,
/// 该画布所属的上级资源(通常为 Manifest)。
///
/// Parent resources (typically a Manifest) this canvas is part of.
#[serde(skip_serializing_if = "Option::is_none")]
pub part_of: Option<Vec<Resource>>,
/// painting 注解所在的 AnnotationPage 列表。
///
/// Annotation pages with `painting` annotations.
pub items: Vec<AnnotationPage>,
/// `supplementing` 等其他注解。
///
/// Additional annotation pages such as `supplementing`.
#[serde(skip_serializing_if = "Option::is_none")]
pub annotations: Option<Vec<AnnotationPage>>,
}
fn canvas_type() -> String {
"Canvas".to_string()
}
impl Default for Canvas {
fn default() -> Self {
Self {
id: "".to_string(),
r#type: canvas_type(),
label: LangMap::default(),
summary: None,
metadata: None,
required_statement: None,
rights: None,
language: None,
height: None,
width: None,
duration: None,
viewing_direction: None,
behavior: None,
thumbnail: None,
homepage: None,
see_also: None,
rendering: None,
service: None,
part_of: None,
items: Vec::new(),
annotations: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_canvas_default() {
let canvas = Canvas::default();
assert_eq!(canvas.id, "");
assert_eq!(canvas.r#type, "Canvas");
}
}