Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion src/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use idna::punycode::decode_to_string;
use pyo3::exceptions::PyValueError;
use pyo3::pyclass::CompareOp;
use pyo3::sync::GILOnceCell;
use pyo3::types::{PyDict, PyType};
use pyo3::types::{PyDict, PyTuple, PyType};
use pyo3::{intern, prelude::*};
use url::Url;

Expand Down Expand Up @@ -190,6 +190,37 @@ impl PyUrl {
}
cls.call1((url,))
}

#[pyo3(signature=(path, *args, no_trailing_slash=false))]
pub fn join(&self, path: &str, args: &Bound<'_, PyTuple>, no_trailing_slash: bool) -> PyResult<Self> {
let join_path = |base: &Url, partial_path: String| -> Result<Url, PyErr> {
base.join(&partial_path)
.map_err(|err| PyValueError::new_err(err.to_string()))
};

let add_trailing_slash = |path_str: &mut String| {
if !path_str.trim_end().ends_with('/') {
path_str.push('/');
}
};

let num_of_args = args.len();
let mut path_str = path.to_string();
if num_of_args != 0 || !no_trailing_slash {
add_trailing_slash(&mut path_str);
}

let mut new_url = join_path(&self.lib_url, path_str)?;

for i in 0..num_of_args {
let mut arg_str = args.get_item(i)?.to_string();
if i != num_of_args - 1 || !no_trailing_slash {
add_trailing_slash(&mut arg_str);
}
new_url = join_path(&new_url, arg_str)?;
}
Ok(PyUrl::new(new_url))
}
}

#[pyclass(name = "MultiHostUrl", module = "pydantic_core._pydantic_core", subclass, frozen)]
Expand Down