use crate::markdown::ast::AstOptions;
use crate::markdown::html::RenderOptions;
#[cfg(feature = "npm")]
use napi_derive::napi;
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "npm", napi(object))]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PeisarOptions {
pub gfm: Option<bool>,
pub kramdown: Option<bool>,
pub file_name: Option<String>,
pub fragment: Option<bool>,
pub charset: Option<bool>,
pub viewport: Option<bool>,
pub title: Option<String>,
pub body_class: Option<String>,
pub style: Option<String>,
}
#[cfg_attr(feature = "npm", napi)]
impl Default for PeisarOptions {
fn default() -> Self {
Self {
gfm: Some(true),
kramdown: Some(true),
file_name: None,
fragment: Some(false),
charset: Some(true),
viewport: Some(true),
title: None,
body_class: None,
style: None,
}
}
}
pub struct GetOptions {
pub ast_opts: AstOptions,
pub render_opts: RenderOptions,
}
pub fn get_options(options: Option<PeisarOptions>) -> GetOptions {
let opts = options.unwrap_or_default();
let ast_opts = AstOptions {
gfm: opts.gfm.unwrap_or(true),
kramdown: opts.kramdown.unwrap_or(true),
file_name: opts.file_name,
};
let render_opts = RenderOptions {
fragment: opts.fragment.unwrap_or(false),
charset: opts.charset.unwrap_or(true),
viewport: opts.viewport.unwrap_or(true),
title: opts.title,
body_class: opts.body_class,
style: opts.style,
};
GetOptions {
ast_opts,
render_opts,
}
}
#[cfg(test)]
mod tests {
use super::{PeisarOptions, get_options};
#[test]
fn partial_options_use_defaults_for_omitted_fields() {
let options = PeisarOptions {
gfm: None,
kramdown: None,
file_name: None,
fragment: Some(true),
charset: None,
viewport: None,
title: None,
body_class: None,
style: None,
};
let resolved = get_options(Some(options));
assert!(resolved.ast_opts.gfm);
assert!(resolved.ast_opts.kramdown);
assert!(resolved.render_opts.fragment);
assert!(resolved.render_opts.charset);
assert!(resolved.render_opts.viewport);
}
#[test]
fn none_resolves_to_documented_defaults() {
let resolved = get_options(None);
assert!(resolved.ast_opts.gfm);
assert!(resolved.ast_opts.kramdown);
assert_eq!(resolved.ast_opts.file_name, None);
assert!(!resolved.render_opts.fragment);
assert!(resolved.render_opts.charset);
assert!(resolved.render_opts.viewport);
assert_eq!(resolved.render_opts.title, None);
assert_eq!(resolved.render_opts.body_class, None);
assert_eq!(resolved.render_opts.style, None);
}
#[test]
fn explicit_values_are_preserved() {
let resolved = get_options(Some(PeisarOptions {
gfm: Some(false),
kramdown: Some(false),
file_name: Some("doc.md".into()),
fragment: Some(false),
charset: Some(false),
viewport: Some(false),
title: Some("T".into()),
body_class: Some("body".into()),
style: Some("s".into()),
}));
assert!(!resolved.ast_opts.gfm);
assert!(!resolved.ast_opts.kramdown);
assert_eq!(resolved.ast_opts.file_name.as_deref(), Some("doc.md"));
assert!(!resolved.render_opts.fragment);
assert!(!resolved.render_opts.charset);
assert!(!resolved.render_opts.viewport);
assert_eq!(resolved.render_opts.title.as_deref(), Some("T"));
assert_eq!(resolved.render_opts.body_class.as_deref(), Some("body"));
assert_eq!(resolved.render_opts.style.as_deref(), Some("s"));
}
}