Skip to content

Commit

Permalink
Separate interpreter selectors into implementation and platform m…
Browse files Browse the repository at this point in the history
…odules (#3332)

Split out of #3266

The "selector" concept doesn't seem well enough defined as-is. For
example, `PythonVersion` belongs there but isn't present. Going for
smaller modules instead.
  • Loading branch information
zanieb authored May 2, 2024
1 parent 5048cce commit c28a280
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 50 deletions.
47 changes: 47 additions & 0 deletions crates/uv-interpreter/src/implementation.rs
Original file line number Diff line number Diff line change
@@ -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<Item = &'static ImplementationName> {
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<Self, Self::Err> {
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())
}
}
3 changes: 2 additions & 1 deletion crates/uv-interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
7 changes: 5 additions & 2 deletions crates/uv-interpreter/src/managed/downloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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")]
Expand Down
6 changes: 4 additions & 2 deletions crates/uv-interpreter/src/managed/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<Self, Self::Err> {
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<Self, PythonSelectorError> {
pub fn from_env() -> Result<Self, Error> {
Ok(Self::new(
Os::from_env()?,
Arch::from_env()?,
Expand All @@ -119,13 +85,13 @@ impl fmt::Display for Os {
}

impl Os {
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
pub(crate) fn from_env() -> Result<Self, Error> {
Self::from_str(std::env::consts::OS)
}
}

impl FromStr for Os {
type Err = PythonSelectorError;
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
Expand All @@ -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())),
}
}
}
Expand All @@ -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<Self, Self::Err> {
match s.to_lowercase().as_str() {
Expand All @@ -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<Self, PythonSelectorError> {
pub(crate) fn from_env() -> Result<Self, Error> {
Self::from_str(std::env::consts::ARCH)
}
}

impl Libc {
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
pub(crate) fn from_env() -> Result<Self, Error> {
// 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()),
}
}
}
Expand Down

0 comments on commit c28a280

Please sign in to comment.