use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct TldrDocument {
pub title: String,
pub description: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub more_information: Option<String>,
pub examples: Vec<TldrExample>,
pub platform: String,
pub language: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub source_path: String,
#[serde(default, skip_serializing_if = "TldrOrigin::is_tldr_pages")]
pub origin: TldrOrigin,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "kebab-case")]
pub enum TldrOrigin {
#[default]
TldrPages,
Embedded,
}
impl TldrOrigin {
#[must_use]
pub const fn is_tldr_pages(&self) -> bool {
matches!(self, Self::TldrPages)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct TldrExample {
pub description: String,
pub command: String,
pub command_parts: Vec<TldrCommandPart>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(
tag = "type",
rename_all = "kebab-case",
rename_all_fields = "camelCase"
)]
pub enum TldrCommandPart {
Text {
value: String,
},
Placeholder {
value: String,
},
}
#[cfg(test)]
mod tests {
use super::{TldrDocument, TldrOrigin};
#[test]
fn origin_is_additive_and_omitted_for_tldr_pages() {
let page = |origin| TldrDocument {
title: "demo".to_owned(),
description: Vec::new(),
more_information: None,
examples: Vec::new(),
platform: "common".to_owned(),
language: "en".to_owned(),
source_path: "/source/demo.md".to_owned(),
origin,
};
let cached = serde_json::to_value(page(TldrOrigin::TldrPages)).expect("cached page");
assert!(cached.get("origin").is_none());
let embedded = serde_json::to_value(page(TldrOrigin::Embedded)).expect("embedded page");
assert_eq!(embedded["origin"], "embedded");
let mut redacted = page(TldrOrigin::TldrPages);
redacted.source_path.clear();
let redacted = serde_json::to_value(redacted).expect("redacted page");
assert!(redacted.get("sourcePath").is_none());
}
}