1use anyhow::{anyhow, Error};
4use cfg_if::cfg_if;
5use cfg_match::cfg_match;
6use std::marker::PhantomData;
7use yew::html::ChildrenRenderer;
8cfg_if! {
9 if #[cfg(feature = "std_web")] {
10 use stdweb::web::{Document, Window};
11 } else if #[cfg(feature = "web_sys")] {
12 use web_sys::{Document, Window};
13 }
14}
15
16pub fn window() -> Window {
18 cfg_match! {
19 feature = "std_web" => stdweb::web::window(),
20 feature = "web_sys" => web_sys::window().expect("no window available"),
21 }
22}
23
24pub fn document() -> Document {
26 cfg_match! {
27 feature = "std_web" => stdweb::web::document(),
28 feature = "web_sys" => window().document().unwrap(),
29 }
30}
31
32pub fn host() -> Result<String, Error> {
35 let location = document()
36 .location()
37 .ok_or_else(|| anyhow!("can't get location"))?;
38
39 #[cfg(feature = "std_web")]
40 let host = location.host().map_err(Error::from)?;
41
42 #[cfg(feature = "web_sys")]
43 let host = location.host().map_err(|e| {
44 anyhow!(e
45 .as_string()
46 .unwrap_or_else(|| String::from("error not recoverable")),)
47 })?;
48
49 Ok(host)
50}
51
52pub fn origin() -> Result<String, Error> {
54 let location = window().location();
55
56 #[cfg(feature = "std_web")]
57 let location = location.ok_or_else(|| anyhow!("can't get location"))?;
58
59 #[cfg(feature = "std_web")]
60 let origin = location.origin().map_err(Error::from)?;
61
62 #[cfg(feature = "web_sys")]
63 let origin = location.origin().map_err(|e| {
64 anyhow!(e
65 .as_string()
66 .unwrap_or_else(|| String::from("error not recoverable")),)
67 })?;
68
69 Ok(origin)
70}
71
72pub fn into_node_iter<IT, T, R>(it: IT) -> impl Iterator<Item = R>
74where
75 IT: IntoIterator<Item = T>,
76 T: Into<R>,
77{
78 it.into_iter().map(|n| n.into())
79}
80
81#[derive(Debug)]
83pub struct NodeSeq<IN, OUT>(Vec<OUT>, PhantomData<IN>);
84
85impl<IN: Into<OUT>, OUT> From<IN> for NodeSeq<IN, OUT> {
86 fn from(val: IN) -> Self {
87 Self(vec![val.into()], PhantomData::default())
88 }
89}
90
91impl<IN: Into<OUT>, OUT> From<Vec<IN>> for NodeSeq<IN, OUT> {
92 fn from(val: Vec<IN>) -> Self {
93 Self(
94 val.into_iter().map(|x| x.into()).collect(),
95 PhantomData::default(),
96 )
97 }
98}
99
100impl<IN: Into<OUT>, OUT> From<ChildrenRenderer<IN>> for NodeSeq<IN, OUT> {
101 fn from(val: ChildrenRenderer<IN>) -> Self {
102 Self(
103 val.into_iter().map(|x| x.into()).collect(),
104 PhantomData::default(),
105 )
106 }
107}
108
109impl<IN, OUT> IntoIterator for NodeSeq<IN, OUT> {
110 type Item = OUT;
111 type IntoIter = std::vec::IntoIter<Self::Item>;
112
113 fn into_iter(self) -> Self::IntoIter {
114 self.0.into_iter()
115 }
116}