rtk_lua/
versioning.rs

1use std::{fmt::Display, path::PathBuf};
2
3use mlua::FromLua;
4use rtk_lua_macros::RtkMeta;
5
6/// The rustc driver version this script is requesting. This enum MUST remain stable. Do not change
7/// or remove any existing, committed values to this. You can only add more.
8#[derive(Clone, Eq, PartialEq, Debug, RtkMeta)]
9pub enum RtkRustcDriverVersion {
10    /// The latest version on crates io. Probably not a great idea to use this!
11    #[rtk_meta(override = string)]
12    CratesIoLatest,
13
14    /// Specific version on crates io.
15    #[rtk_meta(override = string)]
16    CratesIo { major: u32, minor: u32, patch: u32 },
17
18    /// A local version of the driver.
19    #[rtk_meta(override = string)]
20    Local { path: PathBuf },
21}
22
23impl FromLua for RtkRustcDriverVersion {
24    fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
25        let value_str = value.to_string()?;
26        match value_str.as_str() {
27            "latest" => Ok(RtkRustcDriverVersion::CratesIoLatest),
28            local if local.starts_with("local:") => {
29                let path_str = local.trim_start_matches("local:");
30                let path = PathBuf::from(path_str);
31                Ok(RtkRustcDriverVersion::Local { path })
32            }
33            crates_io => {
34                let parts: Vec<&str> = crates_io.split('.').collect();
35                if parts.len() != 3 {
36                    return Err(mlua::Error::external(format!(
37                        "Invalid version format: {crates_io}. Expected format: major.minor.patch",
38                    )));
39                }
40
41                let major = parts[0].parse::<u32>().map_err(|_| {
42                    mlua::Error::external(format!("Invalid major version: {}", parts[0]))
43                })?;
44
45                let minor = parts[1].parse::<u32>().map_err(|_| {
46                    mlua::Error::external(format!("Invalid minor version: {}", parts[1]))
47                })?;
48
49                let patch = parts[2].parse::<u32>().map_err(|_| {
50                    mlua::Error::external(format!("Invalid patch version: {}", parts[2]))
51                })?;
52
53                Ok(RtkRustcDriverVersion::CratesIo {
54                    major,
55                    minor,
56                    patch,
57                })
58            }
59        }
60    }
61}
62
63impl Display for RtkRustcDriverVersion {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        match self {
66            RtkRustcDriverVersion::CratesIoLatest => write!(f, "latest"),
67            RtkRustcDriverVersion::CratesIo {
68                major,
69                minor,
70                patch,
71            } => {
72                write!(f, "{major}.{minor}.{patch}")
73            }
74            RtkRustcDriverVersion::Local { path } => write!(f, "local:{}", path.display()),
75        }
76    }
77}