Skip to content

Commit c92b9a9

Browse files
committed
Deref pypath to string
1 parent 7c332ce commit c92b9a9

File tree

6 files changed

+88
-70
lines changed

6 files changed

+88
-70
lines changed

Cargo.lock

Lines changed: 46 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ regex = "1.11.1"
2727
lazy_static = "1.5.0"
2828
itertools = "0.14.0"
2929
tap = "1.0.1"
30+
derive_more = { version = "1.0.0", features = ["full"] }
3031

3132
[dev-dependencies]
3233
parameterized = "2.0.0"

src/contracts/layers.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ impl Contract for LayeredArchitectureContract {
8686
.to(to)
8787
.excluding_paths_via(except_via),
8888
)?;
89-
if let Some(path) = path { violations.push(ContractViolation::ForbiddenImport {
90-
forbidden_import,
91-
path,
92-
}) };
89+
if let Some(path) = path {
90+
violations.push(ContractViolation::ForbiddenImport {
91+
forbidden_import,
92+
path,
93+
})
94+
};
9395
Ok(violations)
9496
})
9597
.try_reduce(Vec::new, |mut all_violations, violations| -> Result<_> {

src/imports_info/parse/mod.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,37 @@
11
mod ast_visit;
22

3+
use crate::{errors::Error, Pypath};
34
use anyhow::Result;
45
use rustpython_parser::{self, ast::Stmt, source_code::LinearLocator};
56
use std::{fs, path::Path};
6-
7-
use crate::{errors::Error, Pypath};
7+
use tap::Conv;
88

99
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10-
pub(crate) struct AbsoluteOrRelativePypath {
11-
s: String,
12-
}
10+
pub(crate) struct AbsoluteOrRelativePypath(String);
1311

1412
impl AbsoluteOrRelativePypath {
1513
pub fn new(s: &str) -> Self {
16-
AbsoluteOrRelativePypath { s: s.to_string() }
14+
AbsoluteOrRelativePypath(s.to_string())
1715
}
1816

1917
pub fn is_relative(&self) -> bool {
20-
self.s.starts_with(".")
18+
self.0.starts_with(".")
2119
}
2220

2321
pub fn resolve_relative(&self, path: &Path, root_path: &Path) -> Pypath {
2422
if !self.is_relative() {
25-
return Pypath { s: self.s.clone() };
23+
return Pypath::new(&self.0);
2624
}
27-
let trimmed_pypath = self.s.trim_start_matches(".");
25+
let trimmed_pypath = self.0.trim_start_matches(".");
2826
let base_pypath = {
29-
let n = self.s.len() - trimmed_pypath.len();
27+
let n = self.0.len() - trimmed_pypath.len();
3028
let mut base_path = path;
3129
for _ in 0..n {
3230
base_path = base_path.parent().unwrap();
3331
}
3432
Pypath::from_path(base_path, root_path).unwrap()
3533
};
36-
Pypath {
37-
s: base_pypath.s + "." + trimmed_pypath,
38-
}
34+
Pypath::new(&(base_pypath.conv::<String>() + "." + trimmed_pypath))
3935
}
4036
}
4137

src/package_info/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ impl PackageInfo {
427427
pub fn pypath_is_internal<T: IntoPypath>(&self, pypath: T) -> Result<bool> {
428428
let pypath = pypath.into_pypath()?;
429429
let root_pypath = &self.get_root().pypath;
430-
Ok(root_pypath.contains(pypath.borrow()))
430+
Ok(root_pypath.is_equal_to_or_ancestor_of(pypath.borrow()))
431431
}
432432

433433
/// Checks whether the passed pypath is external.

src/pypath.rs

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::borrow::Borrow;
2-
use std::fmt;
32
use std::path::Path;
43
use std::str::FromStr;
54

65
use anyhow::Result;
6+
use derive_more::derive::{Display, Into};
7+
use derive_more::Deref;
78
use lazy_static::lazy_static;
89
use regex::Regex;
910

@@ -27,20 +28,12 @@ lazy_static! {
2728
/// let result = ".foo.bar".parse::<Pypath>();
2829
/// assert!(result.is_err());
2930
/// ```
30-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31-
pub struct Pypath {
32-
pub(crate) s: String,
33-
}
31+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deref, Display, Into)]
32+
pub struct Pypath(String);
3433

3534
impl Pypath {
3635
pub(crate) fn new(s: &str) -> Pypath {
37-
Pypath { s: s.to_string() }
38-
}
39-
}
40-
41-
impl fmt::Display for Pypath {
42-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43-
write!(f, "{}", self.s)
36+
Pypath(s.to_string())
4437
}
4538
}
4639

@@ -56,24 +49,6 @@ impl FromStr for Pypath {
5649
}
5750
}
5851

59-
impl AsRef<str> for Pypath {
60-
fn as_ref(&self) -> &str {
61-
&self.s
62-
}
63-
}
64-
65-
impl From<Pypath> for String {
66-
fn from(value: Pypath) -> Self {
67-
value.s
68-
}
69-
}
70-
71-
impl<'a> From<&'a Pypath> for &'a str {
72-
fn from(value: &'a Pypath) -> Self {
73-
&value.s
74-
}
75-
}
76-
7752
impl Pypath {
7853
pub(crate) fn from_path(path: &Path, root_path: &Path) -> Result<Self> {
7954
let path = path.strip_prefix(root_path.parent().unwrap())?;
@@ -85,7 +60,7 @@ impl Pypath {
8560
Ok(Pypath::new(&s))
8661
}
8762

88-
/// Returns true if the passed pypath is contained by this pypath.
63+
/// Returns true if this pypath is equal to or an ancestor of the passed pypath.
8964
///
9065
/// # Example
9166
///
@@ -95,14 +70,14 @@ impl Pypath {
9570
/// let foo_bar: Pypath = "foo.bar".parse().unwrap();
9671
/// let foo_bar_baz: Pypath = "foo.bar.baz".parse().unwrap();
9772
///
98-
/// assert!(foo_bar.contains(&foo_bar_baz));
99-
/// assert!(!foo_bar_baz.contains(&foo_bar));
73+
/// assert!(foo_bar.is_equal_to_or_ancestor_of(&foo_bar_baz));
74+
/// assert!(!foo_bar_baz.is_equal_to_or_ancestor_of(&foo_bar));
10075
/// ```
101-
pub fn contains(&self, other: &Pypath) -> bool {
102-
self == other || other.s.starts_with(&(self.s.clone() + "."))
76+
pub fn is_equal_to_or_ancestor_of(&self, other: &Pypath) -> bool {
77+
self == other || other.0.starts_with(&(self.0.clone() + "."))
10378
}
10479

105-
/// Returns true if this pypath is contained by the passed pypath.
80+
/// Returns true if this pypath is equal to or a descendant of the passed pypath.
10681
///
10782
/// # Example
10883
///
@@ -112,11 +87,11 @@ impl Pypath {
11287
/// let foo_bar: Pypath = "foo.bar".parse().unwrap();
11388
/// let foo_bar_baz: Pypath = "foo.bar.baz".parse().unwrap();
11489
///
115-
/// assert!(!foo_bar.is_contained_by(&foo_bar_baz));
116-
/// assert!(foo_bar_baz.is_contained_by(&foo_bar));
90+
/// assert!(!foo_bar.is_equal_to_or_descendant_of(&foo_bar_baz));
91+
/// assert!(foo_bar_baz.is_equal_to_or_descendant_of(&foo_bar));
11792
/// ```
118-
pub fn is_contained_by(&self, other: &Pypath) -> bool {
119-
other.contains(self)
93+
pub fn is_equal_to_or_descendant_of(&self, other: &Pypath) -> bool {
94+
other.is_equal_to_or_ancestor_of(self)
12095
}
12196

12297
/// Returns the parent of this pypath.
@@ -132,9 +107,9 @@ impl Pypath {
132107
///assert!(foo_bar_baz.parent() == foo_bar);
133108
/// ```
134109
pub fn parent(&self) -> Self {
135-
let mut v = self.s.split(".").collect::<Vec<_>>();
110+
let mut v = self.0.split(".").collect::<Vec<_>>();
136111
v.pop();
137-
Pypath { s: v.join(".") }
112+
Pypath(v.join("."))
138113
}
139114
}
140115

@@ -208,19 +183,19 @@ mod tests {
208183
}
209184

210185
#[test]
211-
fn test_contains() -> Result<()> {
212-
assert!(Pypath::new("foo.bar").contains(&Pypath::new("foo.bar")));
213-
assert!(Pypath::new("foo.bar").contains(&Pypath::new("foo.bar.baz")));
214-
assert!(!Pypath::new("foo.bar").contains(&Pypath::new("foo")));
186+
fn test_is_equal_or_ancestor() -> Result<()> {
187+
assert!(Pypath::new("foo.bar").is_equal_to_or_ancestor_of(&Pypath::new("foo.bar")));
188+
assert!(Pypath::new("foo.bar").is_equal_to_or_ancestor_of(&Pypath::new("foo.bar.baz")));
189+
assert!(!Pypath::new("foo.bar").is_equal_to_or_ancestor_of(&Pypath::new("foo")));
215190

216191
Ok(())
217192
}
218193

219194
#[test]
220-
fn test_contained_by() -> Result<()> {
221-
assert!(Pypath::new("foo.bar").is_contained_by(&Pypath::new("foo.bar")));
222-
assert!(!Pypath::new("foo.bar").is_contained_by(&Pypath::new("foo.bar.baz")));
223-
assert!(Pypath::new("foo.bar").is_contained_by(&Pypath::new("foo")));
195+
fn test_is_equal_or_descendant() -> Result<()> {
196+
assert!(Pypath::new("foo.bar").is_equal_to_or_descendant_of(&Pypath::new("foo.bar")));
197+
assert!(!Pypath::new("foo.bar").is_equal_to_or_descendant_of(&Pypath::new("foo.bar.baz")));
198+
assert!(Pypath::new("foo.bar").is_equal_to_or_descendant_of(&Pypath::new("foo")));
224199

225200
Ok(())
226201
}

0 commit comments

Comments
 (0)