eio_okta_api/traits/
service.rs

1use std::ops::Deref;
2
3use http::uri::{Authority, Scheme};
4use iri_string::types::{UriAbsoluteStr, UriAbsoluteString};
5
6#[derive(Debug, thiserror::Error)]
7pub enum Error {
8  #[error("http: {0}")]
9  Http(#[from] http::Error),
10  #[error("endpoint: {0}")]
11  Endpoint(#[from] super::endpoint::Error),
12  #[error("validate: {0}")]
13  Validate(#[from] iri_string::validate::Error),
14}
15
16pub trait Service: Sized {
17  fn scheme(&self) -> &Scheme {
18    &Scheme::HTTPS
19  }
20
21  fn authority(&self) -> &Authority;
22
23  fn uri(&self) -> Result<ServiceURI, Error> {
24    ServiceURI::new(self)
25  }
26}
27
28#[derive(Debug, Clone)]
29pub struct ServiceURI(UriAbsoluteString);
30
31impl Deref for ServiceURI {
32  type Target = UriAbsoluteStr;
33  fn deref(&self) -> &Self::Target {
34    self.0.deref()
35  }
36}
37
38impl ServiceURI {
39  fn new<T>(service: &T) -> Result<Self, Error>
40  where
41    T: Service,
42  {
43    let mut uri = iri_string::build::Builder::new();
44
45    uri.scheme(service.scheme().as_str());
46    uri.host(service.authority().host());
47    if let Some(port) = service.authority().port_u16() {
48      uri.port(port)
49    }
50    uri.path("");
51    uri.unset_fragment();
52    uri.unset_query();
53    uri.unset_userinfo();
54    uri.normalize();
55
56    Ok(Self(uri.build::<UriAbsoluteStr>()?.into()))
57  }
58}