Skip to main content

distrib_common/
package_kind.rs

1// This is free and unencumbered software released into the public domain.
2
3use derive_more::{Display, FromStr};
4
5/// A supported package manager.
6#[derive(Clone, Debug, Default, Display, Eq, FromStr, Hash, Ord, PartialEq, PartialOrd)]
7#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
8#[cfg_attr(
9    feature = "serde",
10    serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))
11)]
12#[non_exhaustive]
13pub enum PackageKind {
14    /// See: <https://crates.io/>
15    #[default]
16    Cargo,
17
18    /// See: <https://gleam.run/>
19    Gleam,
20
21    /// See: <https://jsr.io/>
22    Jsr,
23
24    /// See: <https://npmjs.com/>
25    Npm,
26
27    /// See: <https://pub.dev/>
28    Pub,
29
30    /// See: <https://pypi.org/>
31    Python,
32
33    /// See: <https://rubygems.org/>
34    Ruby,
35}
36
37#[cfg(feature = "std")]
38impl TryFrom<&camino::Utf8Path> for PackageKind {
39    type Error = std::io::Error;
40
41    fn try_from(input: &camino::Utf8Path) -> Result<Self, Self::Error> {
42        use PackageKind::*;
43        use std::io::{Error, ErrorKind};
44        Ok(match input.file_name().unwrap_or("") {
45            "Cargo.toml" => Cargo,
46            "gleam.toml" => Gleam,
47            "jsr.json" => Jsr,
48            "package.json" => Npm,
49            "pubspec.yaml" => Pub,
50            "pyproject.toml" => Python,
51            name if name.ends_with(".gemspec") => Ruby,
52            _ => {
53                return Err(Error::new(
54                    ErrorKind::InvalidFilename,
55                    "unrecognized package filename",
56                ));
57            },
58        })
59    }
60}
61
62impl PackageKind {
63    pub const ALL: [Self; 7] = [
64        Self::Cargo,
65        Self::Gleam,
66        Self::Jsr,
67        Self::Npm,
68        Self::Pub,
69        Self::Python,
70        Self::Ruby,
71    ];
72
73    pub fn manifest_name(&self) -> &str {
74        use PackageKind::*;
75        match self {
76            Cargo => "Cargo.toml",
77            Gleam => "gleam.toml",
78            Jsr => "jsr.json",
79            Npm => "package.json",
80            Pub => "pubspec.yaml",
81            Python => "pyproject.toml",
82            Ruby => "*.gemspec", // wildcard
83        }
84    }
85}