forked from astral-sh/ruff
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
146 lines (130 loc) · 3.89 KB
/
lib.rs
File metadata and controls
146 lines (130 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use std::ffi::OsStr;
use std::path::Path;
pub use expression::*;
pub use generated::*;
pub use int::*;
pub use node_index::*;
pub use nodes::*;
pub use operator_precedence::*;
pub use python_version::*;
pub mod comparable;
pub mod docstrings;
mod expression;
pub mod find_node;
mod generated;
pub mod helpers;
pub mod identifier;
mod int;
pub mod name;
mod node;
mod node_index;
mod nodes;
pub mod operator_precedence;
pub mod parenthesize;
mod python_version;
pub mod relocate;
pub mod script;
pub mod statement_visitor;
pub mod stmt_if;
pub mod str;
pub mod str_prefix;
pub mod token;
pub mod traversal;
pub mod types;
pub mod visitor;
pub mod whitespace;
/// The type of a source file.
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
pub enum SourceType {
/// The file contains Python source code.
Python(PySourceType),
/// The file contains TOML.
Toml(TomlSourceType),
/// The file contains Markdown.
Markdown,
}
impl Default for SourceType {
fn default() -> Self {
Self::Python(PySourceType::Python)
}
}
impl<P: AsRef<Path>> From<P> for SourceType {
fn from(path: P) -> Self {
match path.as_ref().file_name() {
Some(filename) if filename == "pyproject.toml" => Self::Toml(TomlSourceType::Pyproject),
Some(filename) if filename == "Pipfile" => Self::Toml(TomlSourceType::Pipfile),
Some(filename) if filename == "poetry.lock" => Self::Toml(TomlSourceType::Poetry),
_ => match path.as_ref().extension() {
Some(ext) if ext == "toml" => Self::Toml(TomlSourceType::Unrecognized),
Some(ext) if ext == "md" || ext == "qmd" => Self::Markdown,
_ => Self::Python(PySourceType::from(path)),
},
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, is_macro::Is)]
pub enum TomlSourceType {
/// The source is a `pyproject.toml`.
Pyproject,
/// The source is a `Pipfile`.
Pipfile,
/// The source is a `poetry.lock`.
Poetry,
/// The source is an unrecognized TOML file.
Unrecognized,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum PySourceType {
/// The source is a Python file (`.py`, `.pyw`).
/// Note: `.pyw` files contain Python code, but do not represent importable namespaces.
/// Consider adding a separate source type later if combining the two causes issues.
#[default]
Python,
/// The source is a Python stub file (`.pyi`).
Stub,
/// The source is a Jupyter notebook (`.ipynb`).
Ipynb,
}
impl PySourceType {
/// Infers the source type from the file extension.
///
/// Falls back to `Python` if the extension is not recognized.
pub fn from_extension(extension: &str) -> Self {
Self::try_from_extension(extension).unwrap_or_default()
}
/// Infers the source type from the file extension.
pub fn try_from_extension(extension: &str) -> Option<Self> {
let ty = match extension {
"py" => Self::Python,
"pyi" => Self::Stub,
"pyw" => Self::Python,
"ipynb" => Self::Ipynb,
_ => return None,
};
Some(ty)
}
pub fn try_from_path(path: impl AsRef<Path>) -> Option<Self> {
path.as_ref()
.extension()
.and_then(OsStr::to_str)
.and_then(Self::try_from_extension)
}
pub const fn is_py_file(self) -> bool {
matches!(self, Self::Python)
}
pub const fn is_stub(self) -> bool {
matches!(self, Self::Stub)
}
pub const fn is_py_file_or_stub(self) -> bool {
matches!(self, Self::Python | Self::Stub)
}
pub const fn is_ipynb(self) -> bool {
matches!(self, Self::Ipynb)
}
}
impl<P: AsRef<Path>> From<P> for PySourceType {
fn from(path: P) -> Self {
Self::try_from_path(path).unwrap_or_default()
}
}