jupyter_protocol/media/
datatable.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4/// See <https://specs.frictionlessdata.io/tabular-data-resource/>
5#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
6#[serde(rename_all = "camelCase")]
7pub struct TabularDataResource {
8    #[serde(skip_serializing_if = "Option::is_none")]
9    pub path: Option<PathOrPaths>,
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub data: Option<Vec<serde_json::Value>>,
12    pub schema: TableSchema,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub title: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub description: Option<String>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub homepage: Option<String>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub sources: Option<Vec<Source>>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub licenses: Option<Vec<License>>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub dialect: Option<Dialect>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub format: Option<String>,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub mediatype: Option<String>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub encoding: Option<String>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub bytes: Option<i64>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub hash: Option<String>,
35}
36
37#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
38#[serde(untagged)]
39pub enum PathOrPaths {
40    Single(String),
41    Multiple(Vec<String>),
42}
43
44#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
45#[serde(rename_all = "camelCase")]
46pub struct TableSchema {
47    pub fields: Vec<TableSchemaField>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub primary_key: Option<PrimaryKey>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub foreign_keys: Option<Vec<ForeignKey>>,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub missing_values: Option<Vec<String>>,
54}
55
56#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
57#[serde(rename_all = "camelCase", untagged)]
58pub enum PrimaryKey {
59    Single(String),
60    Multiple(Vec<String>),
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
64#[serde(rename_all = "camelCase")]
65pub struct ForeignKey {
66    pub fields: ForeignKeyFields,
67    pub reference: ForeignKeyReference,
68}
69
70#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
71#[serde(untagged)]
72pub enum ForeignKeyFields {
73    Single(String),
74    Multiple(Vec<String>),
75}
76
77#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
78#[serde(rename_all = "camelCase")]
79pub struct ForeignKeyReference {
80    pub resource: String,
81    pub fields: ForeignKeyFields,
82}
83
84#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
85#[serde(rename_all = "camelCase")]
86pub struct TableSchemaField {
87    pub name: String,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub title: Option<String>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub description: Option<String>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub example: Option<String>,
94    #[serde(rename = "type")]
95    pub field_type: FieldType,
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub format: Option<FieldFormat>,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub constraints: Option<HashMap<String, serde_json::Value>>,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub rdf_type: Option<String>,
102}
103
104#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
105#[serde(rename_all = "lowercase")]
106pub enum FieldType {
107    String,
108    Number,
109    Integer,
110    Date,
111    Time,
112    Datetime,
113    Year,
114    Yearmonth,
115    Boolean,
116    Object,
117    Geopoint,
118    Geojson,
119    Array,
120    Duration,
121    #[default]
122    Any,
123}
124
125#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
126#[serde(rename_all = "lowercase")]
127pub enum FieldFormat {
128    Default,
129    Email,
130    Uri,
131    Binary,
132    Uuid,
133    Any,
134    Array,
135    Object,
136}
137
138#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
139#[serde(rename_all = "camelCase")]
140pub struct Source {
141    pub title: String,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub path: Option<String>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub email: Option<String>,
146}
147
148#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
149#[serde(rename_all = "camelCase")]
150pub struct License {
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub name: Option<String>,
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub path: Option<String>,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub title: Option<String>,
157}
158
159#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
160#[serde(rename_all = "camelCase")]
161pub struct Dialect {
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub delimiter: Option<String>,
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub double_quote: Option<bool>,
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub line_terminator: Option<String>,
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub null_sequence: Option<String>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub quote_char: Option<String>,
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub escape_char: Option<String>,
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub skip_initial_space: Option<bool>,
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub header: Option<bool>,
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub comment_char: Option<String>,
180    #[serde(skip_serializing_if = "Option::is_none")]
181    pub case_sensitive_header: Option<bool>,
182}