use std::collections::{BTreeMap, HashMap};
use serde::{Deserialize, Serialize};
use serde_json::Value;
fn sort_alphabetically<T: Serialize, S: serde::Serializer>(
value: &T,
serializer: S,
) -> Result<S::Ok, S::Error> {
let value = serde_json::to_value(value).map_err(serde::ser::Error::custom)?;
value.serialize(serializer)
}
#[derive(Serialize)]
pub struct SortAlphabetically<T: Serialize>(#[serde(serialize_with = "sort_alphabetically")] pub T);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct RawNotebook {
pub cells: Vec<Cell>,
pub metadata: RawNotebookMetadata,
pub nbformat: i64,
pub nbformat_minor: i64,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "cell_type")]
pub enum Cell {
#[serde(rename = "code")]
Code(CodeCell),
#[serde(rename = "markdown")]
Markdown(MarkdownCell),
#[serde(rename = "raw")]
Raw(RawCell),
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct RawCell {
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub metadata: CellMetadata,
pub source: SourceValue,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct MarkdownCell {
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub metadata: CellMetadata,
pub source: SourceValue,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct CodeCell {
pub execution_count: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub metadata: CellMetadata,
pub outputs: Vec<Value>,
pub source: SourceValue,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub struct CellMetadata {
#[serde(skip_serializing_if = "Option::is_none")]
pub vscode: Option<CodeCellMetadataVSCode>,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct CodeCellMetadataVSCode {
pub language_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct RawNotebookMetadata {
#[serde(skip_serializing_if = "Option::is_none")]
pub authors: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kernelspec: Option<Kernelspec>,
#[serde(skip_serializing_if = "Option::is_none")]
pub language_info: Option<LanguageInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub orig_nbformat: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(flatten)]
pub extra: BTreeMap<String, Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Kernelspec {
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct LanguageInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub codemirror_mode: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_extension: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mimetype: Option<String>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub pygments_lexer: Option<String>,
#[serde(flatten)]
pub extra: BTreeMap<String, Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum SourceValue {
String(String),
StringArray(Vec<String>),
}