Skip to main content

conduit_cli/core/io/project/
lock.rs

1use crate::core::error::{CoreError, CoreResult};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
6#[serde(rename_all = "lowercase")]
7pub enum ModSide {
8    Server,
9    Client,
10    Both,
11}
12
13#[derive(Serialize, Deserialize, Debug)]
14pub struct ConduitLock {
15    pub version: i32,
16    pub conduit_version: String,
17    pub locked_mods: HashMap<String, LockedMod>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub loader_version: Option<String>,
20}
21
22#[derive(Serialize, Deserialize, Debug)]
23pub struct LockedMod {
24    pub id: String,
25    pub version_id: String,
26    pub filename: String,
27    pub url: String,
28    pub hash: String,
29    pub side: ModSide,
30    pub dependencies: Vec<String>,
31}
32
33impl ConduitLock {
34    pub fn from_toml(content: &str) -> CoreResult<Self> {
35        toml::from_str(content)
36            .map_err(|e| CoreError::RuntimeError(format!("Failed to parse conduit.lock: {}", e)))
37    }
38
39    #[rustfmt::skip]
40    pub fn to_toml_with_header(&self) -> CoreResult<String> {
41        let mut content = String::new();
42
43        content.push_str("# ---------------------------------------------------------------------------- #\n");
44        content.push_str("#                                                                              #\n");
45        content.push_str("#                       THIS FILE IS AUTOMATICALLY GENERATED                   #\n");
46        content.push_str("#                            DO NOT EDIT THIS FILE MANUALLY                    #\n");
47        content.push_str("#                                                                              #\n");
48        content.push_str("# ---------------------------------------------------------------------------- #\n");
49        content.push_str("#                                                                              #\n");
50        content.push_str("#  This file contains the precise reproduction information for the project's   #\n");
51        content.push_str("#  dependencies. Editing it could break your environment synchronization.      #\n");
52        content.push_str("#                                                                              #\n");
53        content.push_str("# ---------------------------------------------------------------------------- #\n\n");
54
55        let serialized = toml::to_string_pretty(self).map_err(|e| {
56            CoreError::RuntimeError(format!("Failed to serialize lock: {}", e))
57        })?;
58
59        content.push_str(&serialized);
60        Ok(content)
61    }
62}
63
64impl Default for ConduitLock {
65    fn default() -> Self {
66        Self {
67            version: 1,
68            conduit_version: env!("CARGO_PKG_VERSION").to_string(),
69            locked_mods: HashMap::new(),
70            loader_version: None,
71        }
72    }
73}