launchdarkly_server_sdk/
feature_requester_builders.rs1use crate::feature_requester::{FeatureRequester, HttpFeatureRequester};
2use crate::LAUNCHDARKLY_TAGS_HEADER;
3use http::Uri;
4use launchdarkly_sdk_transport::HttpTransport;
5use std::collections::HashMap;
6use std::str::FromStr;
7use thiserror::Error;
8
9#[non_exhaustive]
11#[derive(Debug, Error)]
12pub enum BuildError {
13 #[error("feature requester factory failed to build: {0}")]
15 InvalidConfig(String),
16}
17
18pub trait FeatureRequesterFactory: Send {
23 fn build(&self, tags: Option<String>) -> Result<Box<dyn FeatureRequester>, BuildError>;
25}
26
27pub struct HttpFeatureRequesterBuilder<T: HttpTransport> {
28 url: String,
29 sdk_key: String,
30 transport: T,
31}
32
33impl<T: HttpTransport> HttpFeatureRequesterBuilder<T> {
34 pub fn new(url: &str, sdk_key: &str, transport: T) -> Self {
35 Self {
36 transport,
37 url: url.into(),
38 sdk_key: sdk_key.into(),
39 }
40 }
41}
42
43impl<T: HttpTransport> FeatureRequesterFactory for HttpFeatureRequesterBuilder<T> {
44 fn build(&self, tags: Option<String>) -> Result<Box<dyn FeatureRequester>, BuildError> {
45 let url = format!("{}/sdk/latest-all", self.url);
46
47 let mut default_headers = HashMap::<&str, String>::new();
48
49 if let Some(tags) = tags {
50 default_headers.insert(LAUNCHDARKLY_TAGS_HEADER, tags);
51 }
52
53 let url = Uri::from_str(url.as_str())
54 .map_err(|_| BuildError::InvalidConfig("Invalid base url provided".into()))?;
55
56 Ok(Box::new(HttpFeatureRequester::new(
57 self.transport.clone(),
58 url,
59 self.sdk_key.clone(),
60 default_headers,
61 )))
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn factory_handles_url_parsing_failure() {
71 let transport =
72 launchdarkly_sdk_transport::HyperTransport::new().expect("Failed to create transport");
73 let builder = HttpFeatureRequesterBuilder::new(
74 "This is clearly not a valid URL",
75 "sdk-key",
76 transport,
77 );
78 let result = builder.build(None);
79
80 match result {
81 Err(BuildError::InvalidConfig(_)) => (),
82 _ => panic!("Build did not return the right type of error"),
83 };
84 }
85}