feat: Support versioned modules
This commit is contained in:
parent
74bd05643f
commit
2d150e3c93
7 changed files with 135 additions and 19 deletions
|
|
@ -11,11 +11,15 @@ use serde_yaml::Value;
|
|||
|
||||
use crate::{base_recipe_path, AkmodsInfo, ModuleExt};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder, Default)]
|
||||
mod type_ver;
|
||||
|
||||
pub use type_ver::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Builder)]
|
||||
pub struct ModuleRequiredFields<'a> {
|
||||
#[builder(into)]
|
||||
#[serde(rename = "type")]
|
||||
pub module_type: Cow<'a, str>,
|
||||
pub module_type: ModuleTypeVersion<'a>,
|
||||
|
||||
#[builder(into)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -38,7 +42,7 @@ const fn is_false(b: &bool) -> bool {
|
|||
impl<'a> ModuleRequiredFields<'a> {
|
||||
#[must_use]
|
||||
pub fn get_module_type_list(&'a self, typ: &str, list_key: &str) -> Option<Vec<String>> {
|
||||
if self.module_type == typ {
|
||||
if self.module_type.typ() == typ {
|
||||
Some(
|
||||
self.config
|
||||
.get(list_key)?
|
||||
|
|
@ -217,7 +221,7 @@ impl Module<'_> {
|
|||
required_fields: None,
|
||||
from_file: Some(file_name),
|
||||
} => {
|
||||
let file_name = PathBuf::from(file_name.as_ref());
|
||||
let file_name = PathBuf::from(&**file_name);
|
||||
if traversed_files.contains(&file_name) {
|
||||
bail!(
|
||||
"{} File {} has already been parsed:\n{traversed_files:?}",
|
||||
|
|
@ -260,14 +264,21 @@ impl Module<'_> {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(clippy::missing_panics_doc)]
|
||||
pub fn example() -> Self {
|
||||
Self::builder()
|
||||
.required_fields(
|
||||
ModuleRequiredFields::builder()
|
||||
.module_type("module-name")
|
||||
.module_type("script")
|
||||
.config(IndexMap::from_iter([
|
||||
("module".to_string(), Value::String("config".to_string())),
|
||||
("goes".to_string(), Value::String("here".to_string())),
|
||||
(
|
||||
"snippets".to_string(),
|
||||
Value::Sequence(bon::vec!["echo 'Hello World!'"]),
|
||||
),
|
||||
(
|
||||
"scripts".to_string(),
|
||||
Value::Sequence(bon::vec!["install-program.sh"]),
|
||||
),
|
||||
]))
|
||||
.build(),
|
||||
)
|
||||
|
|
|
|||
78
recipe/src/module/type_ver.rs
Normal file
78
recipe/src/module/type_ver.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleTypeVersion<'scope> {
|
||||
typ: Cow<'scope, str>,
|
||||
version: Cow<'scope, str>,
|
||||
}
|
||||
|
||||
impl ModuleTypeVersion<'_> {
|
||||
#[must_use]
|
||||
pub fn typ(&self) -> &str {
|
||||
&self.typ
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn version(&self) -> &str {
|
||||
&self.version
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ModuleTypeVersion<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}@{}", &self.typ, &self.version)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'scope> From<&'scope str> for ModuleTypeVersion<'scope> {
|
||||
fn from(s: &'scope str) -> Self {
|
||||
if let Some((typ, version)) = s.split_once('@') {
|
||||
Self {
|
||||
typ: Cow::Borrowed(typ),
|
||||
version: Cow::Borrowed(version),
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
typ: Cow::Borrowed(s),
|
||||
version: Cow::Owned("latest".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for ModuleTypeVersion<'_> {
|
||||
fn from(s: String) -> Self {
|
||||
if let Some((typ, version)) = s.split_once('@') {
|
||||
Self {
|
||||
typ: Cow::Owned(typ.to_owned()),
|
||||
version: Cow::Owned(version.to_owned()),
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
typ: Cow::Owned(s),
|
||||
version: Cow::Owned("latest".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for ModuleTypeVersion<'_> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for ModuleTypeVersion<'_> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value: String = Deserialize::deserialize(deserializer)?;
|
||||
Ok(value.into())
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ impl ModuleExt<'_> {
|
|||
module
|
||||
.required_fields
|
||||
.as_ref()
|
||||
.is_some_and(|rf| rf.module_type == "akmods")
|
||||
.is_some_and(|rf| rf.module_type.typ() == "akmods")
|
||||
})
|
||||
.filter_map(|module| {
|
||||
Some(
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ impl Stage<'_> {
|
|||
required_fields: None,
|
||||
from_file: Some(file_name),
|
||||
} => {
|
||||
let file_name = PathBuf::from(file_name.as_ref());
|
||||
let file_name = PathBuf::from(&**file_name);
|
||||
if traversed_files.contains(&file_name) {
|
||||
bail!(
|
||||
"{} File {} has already been parsed:\n{traversed_files:?}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue