use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub struct IncompletePackage {
pub name: String,
pub dir: PathBuf,
pub reasons: Vec<IncompleteEntries>,
#[serde(default)]
pub scope: IncompleteScope,
}
impl IncompletePackage {
#[must_use]
pub const fn new(name: String, dir: PathBuf, reasons: Vec<IncompleteEntries>) -> Self {
Self {
name,
dir,
reasons,
scope: IncompleteScope::Package,
}
}
#[must_use]
pub fn with_scope(mut self, scope: IncompleteScope) -> Self {
self.scope = scope;
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum IncompleteScope {
#[default]
Package,
Within(Vec<String>),
}
impl IncompleteScope {
#[must_use]
pub fn union(self, other: Self) -> Self {
match (self, other) {
(Self::Within(mut globs), Self::Within(more)) => {
for glob in more {
if !globs.contains(&glob) {
globs.push(glob);
}
}
Self::Within(globs)
}
_ => Self::Package,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub struct IncompleteEntries {
pub cause: IncompleteCause,
#[serde(skip_serializing_if = "Option::is_none")]
pub plugin: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub file: Option<PathBuf>,
}
impl IncompleteEntries {
#[must_use]
pub const fn new(cause: IncompleteCause) -> Self {
Self {
cause,
plugin: None,
file: None,
}
}
#[must_use]
pub fn with_plugin(mut self, plugin: impl Into<String>) -> Self {
self.plugin = Some(plugin.into());
self
}
#[must_use]
pub fn with_file(mut self, file: impl Into<PathBuf>) -> Self {
self.file = Some(file.into());
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum IncompleteCause {
UnparsableConfig,
UnknownConfig,
UnknownSpread,
ComputedEntries,
UnmappedPublished,
NoEntries,
Unspecified,
}
impl IncompleteCause {
#[must_use]
pub const fn describe(self) -> &'static str {
match self {
Self::UnparsableConfig => "the configuration does not parse",
Self::UnknownConfig => "the configuration evaluates to a value that is not known statically",
Self::UnknownSpread => {
"the configuration spreads or merges in a value that is not known statically (an imported base config)"
}
Self::ComputedEntries => "the keys the tool reads entry files from are computed",
Self::UnmappedPublished => {
"package.json publishes build output or bin files none of which maps back to a source file"
}
Self::NoEntries => "the package has no source file, entry or script of its own",
Self::Unspecified => "an input source reported its entries incomplete",
}
}
}