1use std::path::PathBuf;
4
5use serde::{Deserialize, Serialize};
6use smallvec::SmallVec;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(rename_all = "lowercase")]
11pub enum Language {
12 Js,
13 Ts,
14 Python,
15 Go,
16 Rust,
17}
18
19impl Language {
20 #[inline]
21 pub fn as_str(&self) -> &'static str {
22 match self {
23 Language::Js => "js",
24 Language::Ts => "ts",
25 Language::Python => "python",
26 Language::Go => "go",
27 Language::Rust => "rust",
28 }
29 }
30
31 #[allow(clippy::should_implement_trait)]
35 pub fn from_str(s: &str) -> Option<Self> {
36 match s.to_lowercase().as_str() {
37 "js" | "javascript" => Some(Language::Js),
38 "ts" | "typescript" => Some(Language::Ts),
39 "python" => Some(Language::Python),
40 "go" => Some(Language::Go),
41 "rust" => Some(Language::Rust),
42 _ => None,
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
49pub struct Task {
50 pub name: String,
51 pub command: String,
52 #[serde(default)]
53 pub depends_on: Vec<String>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct Package {
59 pub name: String,
60 pub language: Language,
61 pub public: bool,
62 pub path: PathBuf,
63 #[serde(
64 deserialize_with = "deserialize_deps",
65 serialize_with = "serialize_deps"
66 )]
67 pub deps: SmallVec<[String; 4]>,
68 pub tasks: Vec<Task>,
69 pub version: Option<String>,
70}
71
72fn deserialize_deps<'de, D>(deserializer: D) -> Result<SmallVec<[String; 4]>, D::Error>
73where
74 D: serde::Deserializer<'de>,
75{
76 use serde::Deserialize;
77 let vec: Vec<String> = Vec::deserialize(deserializer)?;
78 Ok(SmallVec::from_vec(vec))
79}
80
81fn serialize_deps<S>(deps: &SmallVec<[String; 4]>, serializer: S) -> Result<S::Ok, S::Error>
82where
83 S: serde::Serializer,
84{
85 use serde::Serialize;
86 let vec: Vec<&String> = deps.iter().collect();
87 vec.serialize(serializer)
88}
89
90impl Package {
91 pub fn new(
92 name: String,
93 language: Language,
94 public: bool,
95 path: PathBuf,
96 deps: Vec<String>,
97 tasks: Vec<Task>,
98 ) -> Self {
99 Self {
100 name,
101 language,
102 public,
103 path,
104 deps: SmallVec::from_vec(deps),
105 tasks,
106 version: None,
107 }
108 }
109
110 #[inline]
111 pub fn get_task(&self, name: &str) -> Option<&Task> {
112 self.tasks.iter().find(|t| t.name == name)
113 }
114}