1use std::{fmt::Display, path::PathBuf};
2
3use mlua::FromLua;
4use rtk_lua_macros::RtkMeta;
5
6#[derive(Clone, Eq, PartialEq, Debug, RtkMeta)]
9pub enum RtkRustcDriverVersion {
10 #[rtk_meta(override = string)]
12 CratesIoLatest,
13
14 #[rtk_meta(override = string)]
16 CratesIo { major: u32, minor: u32, patch: u32 },
17
18 #[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}