use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum PackageSource {
#[default]
Cargo,
Bun,
Npm,
Oci,
}
impl PackageSource {
pub const fn default_execution_class(self) -> Option<&'static str> {
match self {
Self::Cargo => Some("lenso.native-rust@1"),
Self::Bun | Self::Npm => Some("lenso.bun-process@1"),
Self::Oci => None,
}
}
pub const fn as_str(self) -> &'static str {
match self {
Self::Cargo => "cargo",
Self::Bun => "bun",
Self::Npm => "npm",
Self::Oci => "oci",
}
}
}
impl fmt::Display for PackageSource {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct PackageInput {
name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
package_name: Option<String>,
source: PackageSource,
version: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
locked_revision: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
manifest: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
lockfile: Option<String>,
}
impl PackageInput {
pub fn new(name: impl Into<String>, source: PackageSource, version: impl Into<String>) -> Self {
Self {
name: name.into(),
package_name: None,
source,
version: version.into(),
locked_revision: None,
manifest: None,
lockfile: None,
}
}
#[must_use]
pub fn with_package_name(mut self, package_name: impl Into<String>) -> Self {
self.package_name = Some(package_name.into());
self
}
#[must_use]
pub fn with_manifest(mut self, manifest: impl Into<String>) -> Self {
self.manifest = Some(manifest.into());
self
}
#[must_use]
pub fn with_lockfile(mut self, lockfile: impl Into<String>) -> Self {
self.lockfile = Some(lockfile.into());
self
}
#[must_use]
pub fn with_locked_revision(mut self, revision: impl Into<String>) -> Self {
self.locked_revision = Some(revision.into());
self
}
pub fn name(&self) -> &str {
&self.name
}
pub fn package_name(&self) -> &str {
self.package_name.as_deref().unwrap_or(&self.name)
}
pub const fn source(&self) -> PackageSource {
self.source
}
pub fn version(&self) -> &str {
&self.version
}
pub fn locked_revision(&self) -> &str {
self.locked_revision.as_deref().unwrap_or(&self.version)
}
pub fn manifest(&self) -> Option<&str> {
self.manifest.as_deref()
}
pub fn lockfile(&self) -> Option<&str> {
self.lockfile.as_deref()
}
}