cargo_component_core/
lib.rs

1//! Core library of `cargo-component`.
2
3#![deny(missing_docs)]
4
5use std::path::PathBuf;
6use std::str::FromStr;
7
8use anyhow::Context;
9use semver::VersionReq;
10use wasm_pkg_client::PackageRef;
11
12pub mod command;
13pub mod lock;
14pub mod progress;
15pub mod registry;
16pub mod terminal;
17
18/// The root directory name used for default cargo component directories
19pub const CARGO_COMPONENT_DIR: &str = "cargo-component";
20/// The cache directory name used by default
21pub const CACHE_DIR: &str = "cache";
22
23/// Returns the path to the default cache directory, returning an error if a cache directory cannot be found.
24pub fn default_cache_dir() -> anyhow::Result<PathBuf> {
25    dirs::cache_dir()
26        .map(|p| p.join(CARGO_COMPONENT_DIR).join(CACHE_DIR))
27        .ok_or_else(|| anyhow::anyhow!("failed to find cache directory"))
28}
29
30/// A helper that fetches the default directory if the given directory is `None`.
31pub fn cache_dir(dir: Option<PathBuf>) -> anyhow::Result<PathBuf> {
32    match dir {
33        Some(dir) => Ok(dir),
34        None => default_cache_dir(),
35    }
36}
37
38/// Represents a versioned component package name.
39#[derive(Clone)]
40pub struct VersionedPackageName {
41    /// The package name.
42    pub name: PackageRef,
43    /// The optional package version.
44    pub version: Option<VersionReq>,
45}
46
47impl FromStr for VersionedPackageName {
48    type Err = anyhow::Error;
49
50    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
51        match s.split_once('@') {
52            Some((name, version)) => Ok(Self {
53                name: name.parse()?,
54                version: Some(
55                    version
56                        .parse()
57                        .with_context(|| format!("invalid package version `{version}`"))?,
58                ),
59            }),
60            None => Ok(Self {
61                name: s.parse()?,
62                version: None,
63            }),
64        }
65    }
66}