diff --git a/crates/uv-interpreter/src/implementation.rs b/crates/uv-interpreter/src/implementation.rs new file mode 100644 index 000000000000..9fdab3e813c7 --- /dev/null +++ b/crates/uv-interpreter/src/implementation.rs @@ -0,0 +1,47 @@ +use std::{ + fmt::{self, Display}, + str::FromStr, +}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("Unknown Python implementation `{0}`")] + UnknownImplementation(String), +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub enum ImplementationName { + Cpython, +} + +impl ImplementationName { + #[allow(dead_code)] + pub(crate) fn iter() -> impl Iterator { + static NAMES: &[ImplementationName] = &[ImplementationName::Cpython]; + NAMES.iter() + } + + pub fn as_str(&self) -> &str { + match self { + Self::Cpython => "cpython", + } + } +} + +impl FromStr for ImplementationName { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.to_ascii_lowercase().as_str() { + "cpython" => Ok(Self::Cpython), + _ => Err(Error::UnknownImplementation(s.to_string())), + } + } +} + +impl Display for ImplementationName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} diff --git a/crates/uv-interpreter/src/lib.rs b/crates/uv-interpreter/src/lib.rs index 8e507cd07376..b382c4d4d58d 100644 --- a/crates/uv-interpreter/src/lib.rs +++ b/crates/uv-interpreter/src/lib.rs @@ -25,11 +25,12 @@ pub use crate::target::Target; mod environment; mod find_python; +mod implementation; mod interpreter; pub mod managed; +pub mod platform; mod py_launcher; mod python_version; -pub mod selectors; mod target; #[derive(Debug, Error)] diff --git a/crates/uv-interpreter/src/managed/downloads.rs b/crates/uv-interpreter/src/managed/downloads.rs index 22792e7f5689..7f210aec7314 100644 --- a/crates/uv-interpreter/src/managed/downloads.rs +++ b/crates/uv-interpreter/src/managed/downloads.rs @@ -3,7 +3,8 @@ use std::io; use std::path::{Path, PathBuf}; use std::str::FromStr; -use crate::selectors::{Arch, ImplementationName, Libc, Os, PythonSelectorError}; +use crate::implementation::{Error as ImplementationError, ImplementationName}; +use crate::platform::{Arch, Error as PlatformError, Libc, Os}; use crate::PythonVersion; use thiserror::Error; use uv_client::BetterReqwestError; @@ -18,7 +19,9 @@ use uv_fs::Simplified; #[derive(Error, Debug)] pub enum Error { #[error(transparent)] - SelectorError(#[from] PythonSelectorError), + PlatformError(#[from] PlatformError), + #[error(transparent)] + ImplementationError(#[from] ImplementationError), #[error("invalid python version: {0}")] InvalidPythonVersion(String), #[error("download failed")] diff --git a/crates/uv-interpreter/src/managed/find.rs b/crates/uv-interpreter/src/managed/find.rs index 5d1d66090aef..54b6eca1182a 100644 --- a/crates/uv-interpreter/src/managed/find.rs +++ b/crates/uv-interpreter/src/managed/find.rs @@ -3,8 +3,10 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use crate::managed::downloads::Error; -use crate::python_version::PythonVersion; -use crate::selectors::{Arch, Libc, Os}; +use crate::{ + platform::{Arch, Libc, Os}, + python_version::PythonVersion, +}; use once_cell::sync::Lazy; diff --git a/crates/uv-interpreter/src/selectors.rs b/crates/uv-interpreter/src/platform.rs similarity index 73% rename from crates/uv-interpreter/src/selectors.rs rename to crates/uv-interpreter/src/platform.rs index f790763f0dce..f96614d45aff 100644 --- a/crates/uv-interpreter/src/selectors.rs +++ b/crates/uv-interpreter/src/platform.rs @@ -1,14 +1,9 @@ use std::{ - fmt::{self, Display}, + fmt::{self}, str::FromStr, }; use thiserror::Error; -#[derive(Debug, Eq, PartialEq, Clone, Copy)] -pub enum ImplementationName { - Cpython, -} - #[derive(Debug, PartialEq, Clone)] pub struct Platform { os: Os, @@ -51,49 +46,20 @@ pub enum Libc { } #[derive(Error, Debug)] -pub enum PythonSelectorError { +pub enum Error { #[error("Operating system not supported: {0}")] OsNotSupported(String), #[error("Architecture not supported: {0}")] ArchNotSupported(String), #[error("Libc type could not be detected")] LibcNotDetected(), - #[error("Implementation not supported: {0}")] - ImplementationNotSupported(String), -} - -impl ImplementationName { - pub fn as_str(&self) -> &str { - match self { - Self::Cpython => "cpython", - } - } -} - -impl FromStr for ImplementationName { - type Err = PythonSelectorError; - - fn from_str(s: &str) -> Result { - match s { - "cpython" => Ok(Self::Cpython), - _ => Err(PythonSelectorError::ImplementationNotSupported( - s.to_string(), - )), - } - } -} - -impl Display for ImplementationName { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } } impl Platform { pub fn new(os: Os, arch: Arch, libc: Libc) -> Self { Self { os, arch, libc } } - pub fn from_env() -> Result { + pub fn from_env() -> Result { Ok(Self::new( Os::from_env()?, Arch::from_env()?, @@ -119,13 +85,13 @@ impl fmt::Display for Os { } impl Os { - pub(crate) fn from_env() -> Result { + pub(crate) fn from_env() -> Result { Self::from_str(std::env::consts::OS) } } impl FromStr for Os { - type Err = PythonSelectorError; + type Err = Error; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { @@ -138,7 +104,7 @@ impl FromStr for Os { "dragonfly" => Ok(Self::Dragonfly), "illumos" => Ok(Self::Illumos), "haiku" => Ok(Self::Haiku), - _ => Err(PythonSelectorError::OsNotSupported(s.to_string())), + _ => Err(Error::OsNotSupported(s.to_string())), } } } @@ -159,7 +125,7 @@ impl fmt::Display for Arch { } impl FromStr for Arch { - type Err = PythonSelectorError; + type Err = Error; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { @@ -171,24 +137,24 @@ impl FromStr for Arch { "x86" | "i686" | "i386" => Ok(Self::X86), "x86_64" | "amd64" => Ok(Self::X86_64), "s390x" => Ok(Self::S390X), - _ => Err(PythonSelectorError::ArchNotSupported(s.to_string())), + _ => Err(Error::ArchNotSupported(s.to_string())), } } } impl Arch { - pub(crate) fn from_env() -> Result { + pub(crate) fn from_env() -> Result { Self::from_str(std::env::consts::ARCH) } } impl Libc { - pub(crate) fn from_env() -> Result { + pub(crate) fn from_env() -> Result { // TODO(zanieb): Perform this lookup match std::env::consts::OS { "linux" => Ok(Libc::Gnu), "windows" | "macos" => Ok(Libc::None), - _ => Err(PythonSelectorError::LibcNotDetected()), + _ => Err(Error::LibcNotDetected()), } } }