Skip to main content

entrenar/sovereign/nix/
crate_spec.rs

1//! Crate specification for Nix packaging
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6/// Crate specification for Nix packaging
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub struct CrateSpec {
9    /// Crate name
10    pub name: String,
11    /// Local path (if building from source)
12    pub path: Option<PathBuf>,
13    /// Crates.io version (if using published version)
14    pub version: Option<String>,
15    /// Git repository URL (if using git source)
16    pub git: Option<String>,
17    /// Git revision/tag
18    pub rev: Option<String>,
19}
20
21impl CrateSpec {
22    /// Create a crate spec for a local path
23    pub fn local(name: impl Into<String>, path: impl Into<PathBuf>) -> Self {
24        Self { name: name.into(), path: Some(path.into()), version: None, git: None, rev: None }
25    }
26
27    /// Create a crate spec for crates.io version
28    pub fn crates_io(name: impl Into<String>, version: impl Into<String>) -> Self {
29        Self { name: name.into(), path: None, version: Some(version.into()), git: None, rev: None }
30    }
31
32    /// Create a crate spec for git source
33    pub fn git(name: impl Into<String>, url: impl Into<String>, rev: impl Into<String>) -> Self {
34        Self {
35            name: name.into(),
36            path: None,
37            version: None,
38            git: Some(url.into()),
39            rev: Some(rev.into()),
40        }
41    }
42
43    /// Check if this is a local source
44    pub fn is_local(&self) -> bool {
45        self.path.is_some()
46    }
47
48    /// Check if this is a crates.io source
49    pub fn is_crates_io(&self) -> bool {
50        self.version.is_some() && self.git.is_none()
51    }
52
53    /// Check if this is a git source
54    pub fn is_git(&self) -> bool {
55        self.git.is_some()
56    }
57
58    /// Get source string for Nix
59    pub fn nix_source(&self) -> String {
60        if let Some(path) = &self.path {
61            format!("./{}", path.display())
62        } else if let Some(version) = &self.version {
63            format!("crates.io:{version}")
64        } else if let (Some(git), Some(rev)) = (&self.git, &self.rev) {
65            format!("git:{git}?rev={rev}")
66        } else {
67            "unknown".to_string()
68        }
69    }
70}