i3f 0.0.3

A library for IIIF API, including Image, Presentation.
Documentation
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
use serde::{Deserialize, Serialize};

use crate::{
    image::{Format, Quality},
    presentation::{Context, Resource},
};

/// ImageInfo 定义了 IIIF 图像的基本信息
///
/// Several technical properties
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ImageInfo {
    /// `@context` 属性应作为 JSON 表示的第一个键值对出现。它的值必须是 URI `http://iiif.io/api/image/3/context.json`
    /// 或以 URI `http://iiif.io/api/image/3/context.json` 为最后一项的 JSON 数组。`@context` 告诉链接数据处理器如何
    /// 解读图像信息。如果使用扩展,则其上下文定义应包含在这个顶层 `@context` 属性中。
    ///
    /// The @context property should appear as the very first key-value pair of the JSON representation.
    /// Its value must be either the URI `http://iiif.io/api/image/3/context.json` or a JSON array with
    /// the URI `http://iiif.io/api/image/3/context.json` as the last item. The @context tells Linked
    /// Data processors how to interpret the image information. If extensions are used then their
    /// context definitions should be included in this top-level @context property.
    #[serde(rename = "@context", default = "Context::image_default")]
    pub context: Context,

    /// 图像的基础 URI 在 [URI 语法](https://iiif.io/api/image/3.0/#2-uri-syntax)中定义,包括方案、服务器、前缀和标识符,无尾斜杠。
    ///
    /// The base URI of the image as defined in [URI Syntax](https://iiif.io/api/image/3.0/#2-uri-syntax),
    /// including scheme, server, prefix and identifier without a trailing slash.
    pub id: String,

    /// Image API 的类型。该值必须是字符串 `ImageService3`。
    ///
    /// The type for the Image API. The value must be the string `ImageService3`.
    #[serde(default = "image_service3_type")]
    pub r#type: String,

    /// URI `http://iiif.io/api/image`,可用于确定该文档描述的是一个图像服务,该服务是 IIIF 图像 API 的一个版本。
    ///
    /// The URI `http://iiif.io/api/image` which can be used to determine that the document describes
    /// an image service which is a version of the IIIF Image API.
    #[serde(default = "default_image_protocol")]
    pub protocol: String,

    /// 字符串表示服务完全支持的最高[合规等级](https://iiif.io/api/image/3.0/#6-compliance-level-and-profile-document) 。
    /// 该值必须是 `level0`、`level1` 或 `level2` 之一。
    ///
    /// A string indicating the highest [compliance level](https://iiif.io/api/image/3.0/#6-compliance-level-and-profile-document)
    /// which is fully supported by the service. The value must be one of `level0`, `level1`, or `level2`.
    #[serde(default = "Profile::default")]
    pub profile: Profile,

    /// 图像的宽度,以像素为单位。
    ///
    /// The width of the image, in pixels.
    pub width: u32,

    /// 图像的高度,以像素为单位。
    ///
    /// The height of the image, in pixels.
    pub height: u32,

    /// 该图像支持的最大像素宽度。客户端不应期望支持宽度大于此值的请求。如果指定了 `maxHeight`, 则必须指定 `maxWidth`。
    ///
    /// The maximum width in pixels supported for this image. Clients must not expect requests with a width
    /// greater than this value to be supported. `maxWidth` must be specified if `maxHeight` is specified.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_width: Option<u32>,

    /// 该图像支持的最大像素高度。客户端不应期望高度超过此值的请求会被支持。如果指定了 `maxWidth`,而未指定 `maxHeight`,
    /// 那么客户端应推断 `maxHeight = maxWidth`。
    ///
    /// The maximum height in pixels supported for this image. Clients must not expect requests with
    /// a height greater than this value to be supported. If `maxWidth` is specified and `maxHeight` is not,
    /// then clients should infer that `maxHeight = maxWidth`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_height: Option<u32>,

    /// 该图像支持的最大像素面积。客户端不应期望`width * height`大于此值的请求会被支持。
    ///
    /// The maximum area in pixels supported for this image. Clients must not
    /// expect requests with a `width * height` greater than this value to be supported.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_area: Option<u32>,

    /// 用于描述完整图像表示时的首选`width`和`height`的组合列表。对于不支持任意大小请求的服务器,这些可能是唯一可用的大小。
    /// 用这些大小的 `w,h` 语法构建的请求必须由服务器支持,即使任意宽度和高度不支持。
    ///
    /// An array of JSON objects with the height and width properties. These sizes specify preferred values
    /// to be provided in the w,h syntax of the size request parameter for scaled versions of the full image.
    /// In the case of servers that do not support requests for arbitrary sizes, these may be the only sizes
    /// available. A request constructed with the w,h syntax using these sizes must be supported by the server,
    /// even if arbitrary width and height are not.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sizes: Option<Vec<SizeInfo>>,

    /// 支持的瓦片列表
    ///
    /// A list of supported tile values.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tiles: Option<Vec<TileInfo>>,

    /// 支持的格式列表
    ///
    /// extra formats supported by the service.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extra_formats: Option<Vec<Format>>,

    /// 首选格式参数值,按偏好顺序排列。所列格式参数值必须在参考配置文件中指定的值或 `extraFormats` 属性中列出。
    /// (参见[额外功能](https://iiif.io/api/image/3.0/#57-extra-functionality))
    ///
    /// An array of strings that are the preferred format parameter values, arranged in order of preference.
    /// The format parameter values listed must be among those specified in the referenced profile or listed
    /// in the extraFormats property (see [Extra Functionality](https://iiif.io/api/image/3.0/#57-extra-functionality)).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub preferred_formats: Option<Vec<Format>>,

    /// 适用于该图片内容的许可或权利声明。该属性的价值必须是从[知识共享](https://creativecommons.org/licenses/)许可 URI 集合、
    /// [RightsStatements.org](http://rightsstatements.org/page/1.0/) 权利声明 URI 或通过[已知扩展](https://iiif.io/api/registry/)
    /// 注册机制添加的字符串中提取。该属性的加入具有信息价值,例如可以用来展示代表权利主张的图标。
    ///
    /// A license or rights statement applicable to the content of the image. The value of this property must be a string drawn
    /// from the set of [Creative Commons](https://creativecommons.org/licenses/) license URIs, the
    /// [RightsStatements.org](http://rightsstatements.org/page/1.0/) rights statement URIs,
    /// or those added via the [Registry of Known Extensions](https://iiif.io/api/registry/) mechanism.
    /// The inclusion of this property is informative, and for example could be used to display an
    /// icon representing the rights assertions.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rights: Option<String>,

    /// 支持的 Quality 列表
    ///
    /// A list of supported Quality values.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extra_qualities: Option<Vec<Quality>>,

    /// 支持的 Feature 列表
    ///
    /// A list of supported Feature values.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extra_features: Option<Vec<Feature>>,

    /// 指向另一个引用该图像服务的资源的链接,例如指向画布或清单的链接。该值必须是 JSON 对象数组。每个项目必须具备 `id` 和 `type`属性,并且应拥有 `label` 属性。
    ///
    /// A link to another resource that references this image service, for example a link to a Canvas or Manifest. The value must be an array of
    /// JSON objects. Each item must have the `id` and `type` properties, and should have the `label` property.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub part_of: Option<Vec<Resource>>,

    /// 指向与该资源相关的外部机器可读资源的链接,如 XML 或 RDF 描述。应提供外部资源的属性,帮助客户在多个描述(如提供)中选择,并合理利用文档。
    /// 文档的 URI 必须识别特定格式中数据的单一表示。该值必须是 JSON 对象数组。每个项目必须具备 `id` 和 `type` 属性,并应具备`label` 、
    /// `format`和 `profile` 文件属性。
    ///
    /// A link to an external, machine-readable resource that is related to this resource, such as an XML or RDF description.
    /// Properties of the external resource should be given to help the client select between multiple descriptions (if provided),
    /// and to make appropriate use of the document. The URI of the document must identify a single representation of the data
    /// in a particular format. The value must be an array of JSON objects. Each item must have the `id` and `type` properties,
    /// and should have the `label`, `format` and `profile` properties.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub see_also: Option<Vec<Resource>>,

    /// 对客户端可能直接交互以获取额外信息或功能的外部服务的引用,例如指向认证服务的链接。该值必须是 JSON 对象数组。每个对象会根据服务定义拥有属性,
    /// 但必须具备 `id` 和`type`属性,或 `@id` 和 `@type` 属性,以便向后兼容其他 IIIF API。每个对象都应该有一个配置文件属性。
    /// 请参阅[服务注册表](https://iiif.io/api/annex/services/)以了解已知的服务类型。
    ///
    /// A reference to an external service that the client might interact with directly to gain additional information or functionality,
    /// for example a link to an authentication service. The value must be an array of JSON objects. Each object will have properties
    /// depending on the service’s definition, but must have either the `id` and `type` properties, or the `@id` and `@type` properties
    /// for backwards compatibility with other IIIF APIs. Each object should have a profile property. See the
    /// [Service Registry](https://iiif.io/api/annex/services/) for known service types.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub service: Option<Vec<Resource>>,
}

fn image_service3_type() -> String {
    "ImageService3".to_string()
}

fn default_image_protocol() -> String {
    "http://iiif.io/api/image".to_string()
}

impl Default for ImageInfo {
    fn default() -> Self {
        Self {
            id: "".to_string(),
            context: Context::image_default(),
            r#type: image_service3_type(),
            protocol: default_image_protocol(),
            profile: Profile::default(),
            width: 0,
            height: 0,
            max_width: None,
            max_height: None,
            max_area: None,
            sizes: None,
            tiles: None,
            extra_formats: None,
            preferred_formats: None,
            rights: None,
            extra_qualities: None,
            extra_features: None,
            part_of: None,
            see_also: None,
            service: None,
        }
    }
}

/// 服务完全支持的最高[合规等级](https://iiif.io/api/image/3.0/#6-compliance-level-and-profile-document),
/// 该值必须是 `level0`、`level1` 或 `level2` 之一。
///
/// A string indicating the highest compliance level which is fully supported by the service.
/// The value must be one of `level0`, `level1`, or `level2`.
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum Profile {
    #[default]
    Level0,
    Level1,
    Level2,
}

/// 尺寸项,表示图像的宽度和高度。
///
/// A size item, representing the width and height of the image.
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SizeInfo {
    /// 对象类型,如果存在,值必须为字符串 `Size`。
    ///
    /// The object type, if present, must be the string `Size`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<SizeType>,

    /// 图像的宽度,以像素为单位。
    ///
    /// The width of the image, in pixels.
    pub width: u32,

    /// 图像的高度,以像素为单位。
    ///
    /// The height of the image, in pixels.
    pub height: u32,
}

/// 尺寸类型,如果存在,值必须为字符串 `size`。
///
/// The object type, if present, must be the string `size`.
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub enum SizeType {
    #[default]
    Size,
}

/// 瓦片项,表示图像的瓦片信息。
///
/// A tile item, representing the tile information of the image.
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TileInfo {
    /// 对象类型,如果存在,值必须为字符串 `Tile`。
    ///
    /// The object type, if present, must be the string `Tile`.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<TileType>,

    /// 图像预定义图块的分辨率缩放因子集合,用正整数表示,用于整除图像的全尺寸。
    /// 例如,比例因子为 4 表示该服务能够高效地传输图像,图像比例为整幅图像的
    /// 1/4 或 25%。某个比例因子值应仅在`tiles`数组中出现一次。
    ///
    /// The set of resolution scaling factors for the image’s predefined tiles, expressed
    /// as positive integers by which to divide the full size of the image. For example,
    /// a scale factor of 4 indicates that the service can efficiently deliver images at
    /// 1/4 or 25% of the height and width of the full image. A particular scale factor
    /// value should appear only once in the `tiles` array.
    pub scale_factors: Vec<u8>,

    /// 预定义瓦片的像素宽度,以整数表示。
    ///
    /// The width in pixels of the predefined tiles to be requested, given as an integer.
    pub width: u32,

    /// 预定义图块的像素高度,以整数形式表示。如果 JSON 中没有指定,那么它默认与宽度相同,导致方形瓦片。
    ///
    /// The height in pixels of the predefined tiles to be requested, given as an integer.
    /// If it is not specified in the JSON, then it defaults to the same as width, resulting
    /// in square tiles.
    pub height: Option<u32>,
}

/// 瓦片类型,如果存在,值必须为字符串 `Tile`。
///
/// The object type, if present, must be the string `Tile`.
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub enum TileType {
    #[default]
    Tile,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Feature {
    /// 服务的基础 URI 将重定向到图像信息文档
    ///
    /// The base URI of the service will redirect to the image information document.
    BaseUriRedirect,

    /// 图像响应中提供了规范的图像 URI HTTP 链接头。
    ///
    /// The canonical image URI HTTP link header is provided on image responses.
    CanonicalLinkHeader,

    /// 所有响应都提供了 CORSHTTP 头部。
    ///
    /// The CORS HTTP headers are provided on all responses.
    Cors,

    /// JSON-LD 媒体类型在请求时提供。
    ///
    /// The JSON-LD media type is provided when requested.
    JsonldMediaType,

    /// 图像可以绕垂直轴旋转,从而实现内容从左到右的镜像。
    ///
    /// The image may be rotated around the vertical axis, resulting in a left-to-right mirroring of the content.
    Mirroring,

    /// 配置文件 HTTP 链接头在图像响应中提供。
    ///
    /// The profile HTTP link header is provided on image responses.
    ProfileLinkHeader,

    /// 完整图像的区域可按百分比请求。
    ///
    /// Regions of the full image may be requested by percentage.
    RegionByPct,

    /// 像素尺寸可以请求完整图像的区域。
    ///
    /// Regions of the full image may be requested by pixel dimensions.
    RegionByPx,

    /// 可以请求一个方形区域,其中宽度和高度等于完整图像的较短尺寸。
    ///
    /// A square region may be requested, where the width and height
    /// are equal to the shorter dimension of the full image.
    RegionSquare,

    /// 图像旋转请求可以任意角度进行。
    ///
    /// Image rotation may be requested using arbitrary angles.
    RotationArbitrary,

    /// 图像旋转请求可以90度的倍数进行。
    ///
    /// Image rotation may be requested in multiples of 90 degrees.
    RotationBy90s,

    /// 图片尺寸可通过 `!w,h` 格式请求。
    ///
    /// Image size may be requested in the form `!w,h`.
    SizeByConfinedWh,

    /// 图片尺寸可通过 `,h` 格式请求。
    ///
    /// Image size may be requested in the form `,h`.
    SizeByH,

    /// 图片尺寸可通过 `pct:n` 格式请求。
    ///
    /// Image size may be requested in the form `pct:n`.
    SizeByPct,

    /// 图片尺寸可通过 `w,` 格式请求。
    ///
    /// Image size may be requested in the form `w,`.
    SizeByW,

    /// 图片尺寸可通过 `w,h` 格式请求。
    ///
    /// Image size may be requested in the form `w,h`.
    SizeByWh,

    /// 可请求以 `^` 作为前缀的图像尺寸。
    ///
    /// Image sizes prefixed with `^` may be requested.
    SizeUpscaling,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_profile() {
        let profile = Profile::default();
        assert_eq!(profile, Profile::Level0);
    }

    #[test]
    fn test_image_info() {
        let info = ImageInfo::default();
        assert_eq!(info.r#type, "ImageService3");
        assert_eq!(info.protocol, "http://iiif.io/api/image");
        assert_eq!(info.profile, Profile::Level0);
    }
}