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
//! [JSDoc](https://jsdoc.app) language exporter.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(
html_logo_url = "https://github.com/oscartbeaumont/specta/raw/main/.github/logo-128.png",
html_favicon_url = "https://github.com/oscartbeaumont/specta/raw/main/.github/logo-128.png"
)]
use std::{borrow::Cow, path::Path};
use specta::{Language, TypeMap};
use specta_typescript::{BigIntExportBehavior, CommentFormatterFn, FormatterFn};
// TODO: Ensure this is up to our `Typescript` exporters standards.
/// JSDoc language exporter.
#[derive(Debug, Clone, Default)]
pub struct JSDoc(pub specta_typescript::Typescript);
impl From<specta_typescript::Typescript> for JSDoc {
fn from(ts: specta_typescript::Typescript) -> Self {
Self(ts)
}
}
impl JSDoc {
/// Construct a new JSDoc exporter with the default options configured.
pub fn new() -> Self {
Default::default()
}
/// Configure a header for the file.
///
/// This is perfect for configuring lint ignore rules or other file-level comments.
pub fn header(mut self, header: impl Into<Cow<'static, str>>) -> Self {
self.0.header = header.into();
self
}
// TODO: Only keep this is TS stays responsible for exporting which it probs won't.
/// Removes the default Specta header from the output.
pub fn remove_default_header(mut self) -> Self {
self.0.remove_default_header = true;
self
}
/// Configure the BigInt handling behaviour
pub fn bigint(mut self, bigint: BigIntExportBehavior) -> Self {
self.0.bigint = bigint;
self
}
/// Configure a function which is responsible for styling the comments to be exported
///
/// Implementations:
/// - [`js_doc`](specta_typescript::lang::ts::js_doc)
///
/// Not calling this method will default to the [`js_doc`](specta_typescript::lang::ts::js_doc) exporter.
/// `None` will disable comment exporting.
/// `Some(exporter)` will enable comment exporting using the provided exporter.
pub fn comment_style(mut self, exporter: CommentFormatterFn) -> Self {
self.0.comment_exporter = Some(exporter);
self
}
/// Configure a function which is responsible for formatting the result file or files
///
///
/// Built-in implementations:
/// - [`prettier`](specta_typescript:formatter:::prettier)
/// - [`ESLint`](specta_typescript::formatter::eslint)
/// - [`Biome`](specta_typescript::formatter::biome)e
pub fn formatter(mut self, formatter: FormatterFn) -> Self {
self.0.formatter = Some(formatter);
self
}
}
impl Language for JSDoc {
type Error = specta_typescript::ExportError; // TODO: Custom error type
// TODO: Make this properly export JSDoc
fn export(&self, type_map: TypeMap) -> Result<String, Self::Error> {
todo!("Coming soon...");
// let mut out = self.0.header.to_string();
// if !self.0.remove_default_header {
// out += "// This file has been generated by Specta. DO NOT EDIT.\n\n";
// }
// if let Some((ty_name, l0, l1)) = detect_duplicate_type_names(&type_map).into_iter().next() {
// return Err(ExportError::DuplicateTypeName(ty_name, l0, l1));
// }
// for (_, ty) in type_map.iter() {
// is_valid_ty(&ty.inner, &type_map)?;
// out += &export_named_datatype(&self.0, ty, &type_map)?;
// out += "\n\n";
// }
// Ok(out)
}
fn format(&self, path: &Path) -> Result<(), Self::Error> {
if let Some(formatter) = self.0.formatter {
formatter(path)?;
}
Ok(())
}
}