use std::collections::BTreeMap;
use ecow::EcoString;
use typst_syntax::package::PackageInfo;
use typst_syntax::package::PackageManifest;
use typst_syntax::package::PackageVersion;
use typst_syntax::package::TemplateInfo;
use typst_syntax::package::ToolInfo;
use typst_syntax::package::UnknownFields;
use typst_syntax::package::VersionBound;
#[derive(Debug, Clone)]
pub struct PackageManifestBuilder {
pub package: PackageInfoBuilder,
pub template: Option<TemplateInfoBuilder>,
pub tool: ToolInfoBuilder,
}
impl Default for PackageManifestBuilder {
fn default() -> Self {
Self::new()
}
}
impl PackageManifestBuilder {
pub fn new() -> Self {
Self {
package: PackageInfoBuilder::new(),
template: None,
tool: ToolInfoBuilder::new(),
}
}
pub fn package<T: Into<PackageInfoBuilder>>(&mut self, value: T) -> &mut Self {
self.package = value.into();
self
}
pub fn template<T: Into<TemplateInfoBuilder>>(&mut self, value: T) -> &mut Self {
self.template = Some(value.into());
self
}
pub fn tool<T: Into<ToolInfoBuilder>>(&mut self, value: T) -> &mut Self {
self.tool = value.into();
self
}
pub fn build(&self) -> PackageManifest {
self.clone().into()
}
}
#[derive(Debug, Clone)]
pub struct PackageInfoBuilder {
pub name: EcoString,
pub version: PackageVersion,
pub entrypoint: EcoString,
pub authors: Vec<EcoString>,
pub license: Option<EcoString>,
pub description: Option<EcoString>,
pub homepage: Option<EcoString>,
pub repository: Option<EcoString>,
pub keywords: Vec<EcoString>,
pub categories: Vec<EcoString>,
pub disciplines: Vec<EcoString>,
pub compiler: Option<VersionBound>,
pub exclude: Vec<EcoString>,
}
impl From<PackageManifest> for PackageManifestBuilder {
fn from(value: PackageManifest) -> Self {
Self {
package: value.package.into(),
template: value.template.map(Into::into),
tool: value.tool.into(),
}
}
}
impl From<PackageManifestBuilder> for PackageManifest {
fn from(value: PackageManifestBuilder) -> Self {
Self {
package: value.package.into(),
template: value.template.map(Into::into),
tool: value.tool.into(),
unknown_fields: UnknownFields::new(),
}
}
}
const PACKAGE_INFO_VERSION_DEFAULT: PackageVersion = PackageVersion {
major: 0,
minor: 1,
patch: 0,
};
const PACKAGE_INFO_NAME_DEFAULT: &str = "my-package";
const PACKAGE_INFO_ENTRYPOINT_DEFAULT: &str = "src/lib.typ";
impl Default for PackageInfoBuilder {
fn default() -> Self {
Self::new()
}
}
impl PackageInfoBuilder {
pub fn new() -> Self {
Self {
name: PACKAGE_INFO_NAME_DEFAULT.into(),
version: PACKAGE_INFO_VERSION_DEFAULT,
entrypoint: PACKAGE_INFO_ENTRYPOINT_DEFAULT.into(),
authors: vec![],
license: None,
description: None,
homepage: None,
repository: None,
keywords: vec![],
categories: vec![],
disciplines: vec![],
compiler: None,
exclude: vec![],
}
}
pub fn name<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.name = value.into();
self
}
pub fn version<T: Into<PackageVersion>>(&mut self, value: T) -> &mut Self {
self.version = value.into();
self
}
pub fn entrypoint<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.entrypoint = value.into();
self
}
pub fn authors<T, I>(&mut self, value: I) -> &mut Self
where
T: Into<EcoString>,
I: IntoIterator<Item = T>,
{
self.authors = value.into_iter().map(Into::into).collect();
self
}
pub fn license<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.license = Some(value.into());
self
}
pub fn description<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.description = Some(value.into());
self
}
pub fn homepage<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.homepage = Some(value.into());
self
}
pub fn repository<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.repository = Some(value.into());
self
}
pub fn keywords<T, I>(&mut self, value: I) -> &mut Self
where
T: Into<EcoString>,
I: IntoIterator<Item = T>,
{
self.keywords = value.into_iter().map(Into::into).collect();
self
}
pub fn categories<T, I>(&mut self, value: I) -> &mut Self
where
T: Into<EcoString>,
I: IntoIterator<Item = T>,
{
self.categories = value.into_iter().map(Into::into).collect();
self
}
pub fn disciplines<T, I>(&mut self, value: I) -> &mut Self
where
T: Into<EcoString>,
I: IntoIterator<Item = T>,
{
self.disciplines = value.into_iter().map(Into::into).collect();
self
}
pub fn compiler<T: Into<VersionBound>>(&mut self, value: T) -> &mut Self {
self.compiler = Some(value.into());
self
}
pub fn exclude<T, I>(&mut self, value: I) -> &mut Self
where
T: Into<EcoString>,
I: IntoIterator<Item = T>,
{
self.exclude = value.into_iter().map(Into::into).collect();
self
}
pub fn build(&self) -> PackageInfo {
self.clone().into()
}
}
impl From<PackageInfo> for PackageInfoBuilder {
fn from(value: PackageInfo) -> Self {
Self {
name: value.name,
version: value.version,
entrypoint: value.entrypoint,
authors: value.authors,
license: value.license,
description: value.description,
homepage: value.homepage,
repository: value.repository,
keywords: value.keywords,
categories: value.categories,
disciplines: value.disciplines,
compiler: value.compiler,
exclude: value.exclude,
}
}
}
impl From<PackageInfoBuilder> for PackageInfo {
fn from(value: PackageInfoBuilder) -> Self {
Self {
name: value.name,
version: value.version,
entrypoint: value.entrypoint,
authors: value.authors,
license: value.license,
description: value.description,
homepage: value.homepage,
repository: value.repository,
keywords: value.keywords,
categories: value.categories,
disciplines: value.disciplines,
compiler: value.compiler,
exclude: value.exclude,
unknown_fields: UnknownFields::new(),
}
}
}
const TEMPLATE_INFO_PATH_DEFAULT: &str = "template";
const TEMPLATE_INFO_ENTRYPOINT_DEFAULT: &str = "main.typ";
#[derive(Debug, Clone)]
pub struct TemplateInfoBuilder {
path: EcoString,
entrypoint: EcoString,
thumbnail: Option<EcoString>,
}
impl Default for TemplateInfoBuilder {
fn default() -> Self {
Self::new()
}
}
impl TemplateInfoBuilder {
pub fn new() -> Self {
Self {
path: TEMPLATE_INFO_PATH_DEFAULT.into(),
entrypoint: TEMPLATE_INFO_ENTRYPOINT_DEFAULT.into(),
thumbnail: None,
}
}
pub fn path<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.path = value.into();
self
}
pub fn entrypoint<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.entrypoint = value.into();
self
}
pub fn thumbnail<T: Into<EcoString>>(&mut self, value: T) -> &mut Self {
self.thumbnail = Some(value.into());
self
}
pub fn build(&self) -> TemplateInfo {
self.clone().into()
}
}
impl From<TemplateInfo> for TemplateInfoBuilder {
fn from(value: TemplateInfo) -> Self {
Self {
path: value.path,
entrypoint: value.entrypoint,
thumbnail: value.thumbnail,
}
}
}
impl From<TemplateInfoBuilder> for TemplateInfo {
fn from(value: TemplateInfoBuilder) -> Self {
Self {
path: value.path,
entrypoint: value.entrypoint,
thumbnail: value.thumbnail,
unknown_fields: UnknownFields::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct ToolInfoBuilder {
pub sections: BTreeMap<EcoString, toml::Table>,
}
impl Default for ToolInfoBuilder {
fn default() -> Self {
Self::new()
}
}
impl ToolInfoBuilder {
pub fn new() -> Self {
Self {
sections: BTreeMap::new(),
}
}
pub fn section<T: Into<BTreeMap<EcoString, toml::Table>>>(mut self, value: T) -> Self {
self.sections = value.into();
self
}
pub fn with_section<K: Into<EcoString>, V: Into<toml::Table>>(
mut self,
key: K,
val: V,
) -> Self {
self.sections.insert(key.into(), val.into());
self
}
pub fn build(&self) -> ToolInfo {
self.clone().into()
}
}
impl From<ToolInfo> for ToolInfoBuilder {
fn from(value: ToolInfo) -> Self {
Self {
sections: value.sections,
}
}
}
impl From<ToolInfoBuilder> for ToolInfo {
fn from(value: ToolInfoBuilder) -> Self {
Self {
sections: value.sections,
}
}
}