cobble-core 1.2.0

Library for managing, installing and launching Minecraft instances and more.
Documentation
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};

/// A library needed for running the game with fabric.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct FabricLibrary {
    /// Name of the library.
    pub name: String,
    /// Base URL of the library.
    pub url: String,
}

impl FabricLibrary {
    /// Builds the name of the library jar file.
    pub fn jar_name(&self) -> String {
        let split = self.split_name();
        // Take name and version
        let parts = split.iter().skip(1).take(2).cloned();
        // Take suffixes
        let suffixes = split.iter().skip(3).cloned();

        let mut name = vec![];

        // Name & version
        name.extend(parts);

        // Suffixes
        name.extend(suffixes);

        let mut name = name.join("-");
        name.push_str(".jar");

        name
    }

    /// Builds the path where the library jar file is placed.
    /// This path does not include the file itself.
    pub fn library_path(&self, libraries_path: impl AsRef<Path>) -> PathBuf {
        let mut library_path = PathBuf::from(libraries_path.as_ref());

        library_path.push(self.relative_library_path());

        library_path
    }

    /// Builds the path where the library jar file is placed relative to the libraries folder.
    /// This path does not include the file itself.
    pub fn relative_library_path(&self) -> PathBuf {
        // Take package, name and version
        let path_parts = self.split_name().into_iter().take(3);

        let mut library_path = PathBuf::new();
        for (i, path_part) in path_parts.enumerate() {
            let part = match i {
                0 => path_part.replace('.', "/"),
                _ => path_part,
            };

            library_path.push(part);
        }

        library_path
    }

    /// Builds the complete path for the library jar file.
    pub fn jar_path(&self, libraries_path: impl AsRef<Path>) -> PathBuf {
        let mut jar_path = self.library_path(&libraries_path);
        jar_path.push(self.jar_name());

        jar_path
    }

    /// Builds the complete path for the library jar file relative to the libraries folder.
    pub fn relative_jar_path(&self) -> PathBuf {
        let mut jar_path = self.relative_library_path();
        jar_path.push(self.jar_name());

        jar_path
    }

    pub fn download_url(&self) -> String {
        // Take package, name and version
        let parts = self.split_name().into_iter().take(3);

        let mut base_url = self.url.clone();
        if base_url.ends_with('/') {
            base_url.pop();
        }
        let mut url = vec![base_url];

        for (i, part) in parts.enumerate() {
            if i == 0 {
                url.push(part.replace('.', "/"));
            } else {
                url.push(part);
            }
        }

        url.push(self.jar_name());

        url.join("/")
    }

    fn split_name(&self) -> Vec<String> {
        self.name.split(':').map(String::from).collect()
    }
}