ploidy_codegen_rust/
client.rs1use ploidy_core::codegen::IntoCode;
2use proc_macro2::TokenStream;
3use quote::{ToTokens, TokenStreamExt, quote};
4
5use super::{
6 cfg::CfgFeature,
7 graph::CodegenGraph,
8 naming::{CargoFeature, CodegenIdentUsage},
9};
10
11#[derive(Clone, Copy, Debug)]
13pub struct CodegenClientModule<'a> {
14 graph: &'a CodegenGraph<'a>,
15 features: &'a [&'a CargoFeature],
16}
17
18impl<'a> CodegenClientModule<'a> {
19 pub fn new(graph: &'a CodegenGraph<'a>, features: &'a [&'a CargoFeature]) -> Self {
20 Self { graph, features }
21 }
22}
23
24impl ToTokens for CodegenClientModule<'_> {
25 fn to_tokens(&self, tokens: &mut TokenStream) {
26 let mods = self.features.iter().map(|feature| {
27 let cfg = CfgFeature::for_resource_module(feature);
28 let mod_name = CodegenIdentUsage::Module(feature.as_ident());
29 quote! {
30 #cfg
31 pub mod #mod_name;
32 }
33 });
34
35 let client_doc = {
36 let info = self.graph.spec().info;
37 format!("API client for {} (version {})", info.title, info.version)
38 };
39
40 tokens.append_all(quote! {
41 #[doc = #client_doc]
42 #[derive(Clone, Debug)]
43 pub struct Client {
44 client: ::ploidy_util::reqwest::Client,
45 headers: ::ploidy_util::http::HeaderMap,
46 base_url: ::ploidy_util::url::Url,
47 }
48
49 impl Client {
50 pub fn new(base_url: impl AsRef<str>) -> Result<Self, crate::error::Error> {
52 Ok(Self::with_reqwest_client(
53 ::ploidy_util::reqwest::Client::new(),
54 base_url.as_ref().parse()?,
55 ))
56 }
57
58 pub fn with_reqwest_client(client: ::ploidy_util::reqwest::Client, base_url: ::ploidy_util::url::Url) -> Self {
59 Self {
60 client,
61 headers: ::ploidy_util::http::HeaderMap::new(),
62 base_url,
63 }
64 }
65
66 pub fn with_header<K, V>(mut self, name: K, value: V) -> Result<Self, crate::error::Error>
68 where
69 K: TryInto<::ploidy_util::http::HeaderName>,
70 V: TryInto<::ploidy_util::http::HeaderValue>,
71 K::Error: Into<::ploidy_util::http::Error>,
72 V::Error: Into<::ploidy_util::http::Error>,
73 {
74 let name = name
75 .try_into()
76 .map_err(|err| crate::error::Error::BadHeaderName(err.into()))?;
77 let value = value
78 .try_into()
79 .map_err(|err| crate::error::Error::BadHeaderValue(name.clone(), err.into()))?;
80 self.headers.insert(name, value);
81 Ok(Self {
82 client: self.client,
83 headers: self.headers,
84 base_url: self.base_url,
85 })
86 }
87
88 pub fn with_sensitive_header<K, V>(self, name: K, value: V) -> Result<Self, crate::error::Error>
101 where
102 K: TryInto<::ploidy_util::http::HeaderName>,
103 V: TryInto<::ploidy_util::http::HeaderValue>,
104 K::Error: Into<::ploidy_util::http::Error>,
105 V::Error: Into<::ploidy_util::http::Error>,
106 {
107 let name = name
108 .try_into()
109 .map_err(|err| crate::error::Error::BadHeaderName(err.into()))?;
110 let mut value: ::ploidy_util::http::HeaderValue = value
111 .try_into()
112 .map_err(|err| crate::error::Error::BadHeaderValue(name.clone(), err.into()))?;
113 value.set_sensitive(true);
114 self.with_header(name, value)
115 }
116
117 pub fn with_user_agent<V>(self, value: V) -> Result<Self, crate::error::Error>
118 where
119 V: TryInto<::ploidy_util::http::HeaderValue>,
120 V::Error: Into<::ploidy_util::http::Error>,
121 {
122 self.with_header(::ploidy_util::http::header::USER_AGENT, value)
123 }
124 }
125
126 #(#mods)*
127 });
128 }
129}
130
131impl IntoCode for CodegenClientModule<'_> {
132 type Code = (&'static str, TokenStream);
133
134 fn into_code(self) -> Self::Code {
135 ("src/client/mod.rs", self.into_token_stream())
136 }
137}