pytauri_core/ext_mod_impl/lib/
url.rs1use std::{borrow::Cow, convert::Infallible, path::PathBuf};
2
3use pyo3::{exceptions::PyValueError, prelude::*, types::PyString, FromPyObject, IntoPyObject};
4
5use crate::utils::non_exhaustive_panic;
6
7type TauriUrl = tauri::Url;
8
9pub struct Url<'a>(pub Cow<'a, TauriUrl>);
11
12impl From<TauriUrl> for Url<'_> {
13 fn from(url: TauriUrl) -> Self {
14 Self(Cow::Owned(url))
15 }
16}
17impl<'a> From<&'a TauriUrl> for Url<'a> {
18 fn from(url: &'a TauriUrl) -> Self {
19 Self(Cow::Borrowed(url))
20 }
21}
22
23impl From<Url<'_>> for TauriUrl {
24 fn from(url: Url<'_>) -> Self {
25 url.0.into_owned()
26 }
27}
28
29impl AsRef<TauriUrl> for Url<'_> {
30 fn as_ref(&self) -> &TauriUrl {
31 &self.0
32 }
33}
34
35impl<'py> FromPyObject<'py> for Url<'_> {
36 fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
37 let url: Cow<'_, str> = ob.extract()?;
39 let url = TauriUrl::parse(&url).map_err(|e| PyValueError::new_err(e.to_string()))?;
41 Ok(Self::from(url))
42 }
43}
44
45impl<'py> IntoPyObject<'py> for &Url<'_> {
46 type Target = PyString;
47 type Output = Bound<'py, Self::Target>;
48 type Error = Infallible;
49
50 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
51 let url = PyString::new(py, self.0.as_str());
52 Ok(url)
53 }
54}
55
56impl<'py> IntoPyObject<'py> for Url<'_> {
57 type Target = PyString;
58 type Output = Bound<'py, Self::Target>;
59 type Error = Infallible;
60
61 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
62 (&self).into_pyobject(py)
63 }
64}
65
66#[pyclass(frozen)]
68#[non_exhaustive]
69pub enum WebviewUrl {
70 External(Url<'static>),
71 App(PathBuf),
72 CustomProtocol(Url<'static>),
73 _NonExhaustive(),
74}
75
76impl WebviewUrl {
77 #[expect(dead_code)] pub(crate) fn from_tauri(value: tauri::WebviewUrl) -> Self {
79 match value {
80 tauri::WebviewUrl::External(url) => Self::External(url.into()),
81 tauri::WebviewUrl::App(path) => Self::App(path),
82 tauri::WebviewUrl::CustomProtocol(url) => Self::CustomProtocol(url.into()),
83 _ => Self::_NonExhaustive(),
84 }
85 }
86
87 pub(crate) fn to_tauri(&self) -> PyResult<tauri::WebviewUrl> {
88 let value = match self {
90 Self::External(url) => tauri::WebviewUrl::External(url.0.clone().into_owned()),
91 Self::App(path) => tauri::WebviewUrl::App(path.clone()),
92 Self::CustomProtocol(url) => {
93 tauri::WebviewUrl::CustomProtocol(url.0.clone().into_owned())
94 }
95 Self::_NonExhaustive() => non_exhaustive_panic(),
96 };
97 Ok(value)
98 }
99}