pytauri_core/ext_mod_impl/lib/
url.rs

1use std::{borrow::Cow, convert::Infallible};
2
3use pyo3::{exceptions::PyValueError, prelude::*, types::PyString, FromPyObject, IntoPyObject};
4
5type TauriUrl = tauri::Url;
6
7/// See also: [tauri::Url]
8pub struct Url<'a>(Cow<'a, TauriUrl>);
9
10impl From<TauriUrl> for Url<'_> {
11    fn from(url: TauriUrl) -> Self {
12        Self(Cow::Owned(url))
13    }
14}
15impl<'a> From<&'a TauriUrl> for Url<'a> {
16    fn from(url: &'a TauriUrl) -> Self {
17        Self(Cow::Borrowed(url))
18    }
19}
20
21impl From<Url<'_>> for TauriUrl {
22    fn from(url: Url<'_>) -> Self {
23        url.0.into_owned()
24    }
25}
26
27impl<'py> FromPyObject<'py> for Url<'_> {
28    fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
29        let url: Cow<'_, str> = ob.extract()?; // TODO, PERF: once we drop py39, we can use `&str` directly
30        let url = TauriUrl::parse(&url).map_err(|e| PyValueError::new_err(e.to_string()))?;
31        Ok(Self::from(url))
32    }
33}
34
35impl<'py> IntoPyObject<'py> for &Url<'_> {
36    type Target = PyString;
37    type Output = Bound<'py, Self::Target>;
38    type Error = Infallible;
39
40    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
41        let url = PyString::new(py, self.0.as_str());
42        Ok(url)
43    }
44}
45
46impl<'py> IntoPyObject<'py> for Url<'_> {
47    type Target = PyString;
48    type Output = Bound<'py, Self::Target>;
49    type Error = Infallible;
50
51    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
52        (&self).into_pyobject(py)
53    }
54}