aws_smithy_http_server/schema/
settings.rs1use aws_smithy_types::{Document, Number};
9
10use crate::schema::routing::RouterBuildError;
11
12pub trait FromSetting<'a>: Sized {
17 const EXPECTED: &'static str;
19
20 fn from_setting(value: &'a Document) -> Option<Self>;
22}
23
24impl FromSetting<'_> for bool {
25 const EXPECTED: &'static str = "a boolean";
26
27 fn from_setting(value: &Document) -> Option<Self> {
28 value.as_bool()
29 }
30}
31
32impl FromSetting<'_> for u64 {
33 const EXPECTED: &'static str = "a non-negative integer";
34
35 fn from_setting(value: &Document) -> Option<Self> {
36 match value {
37 Document::Number(Number::PosInt(value)) => Some(*value),
38 _ => None,
39 }
40 }
41}
42
43impl<'a> FromSetting<'a> for &'a str {
44 const EXPECTED: &'static str = "a string";
45
46 fn from_setting(value: &'a Document) -> Option<Self> {
47 value.as_string()
48 }
49}
50
51impl FromSetting<'_> for String {
52 const EXPECTED: &'static str = "a string";
53
54 fn from_setting(value: &Document) -> Option<Self> {
55 value.as_string().map(str::to_owned)
56 }
57}
58
59pub fn get<'a, T: FromSetting<'a>>(settings: Option<&'a Document>, key: &str) -> Result<Option<T>, RouterBuildError> {
65 let Some(settings) = settings else {
66 return Ok(None);
67 };
68 let Document::Object(object) = settings else {
69 return Err(RouterBuildError::Configuration(format!(
70 "settings section for `{key}` (expected {}) must be a JSON object, got {settings:?}",
71 T::EXPECTED,
72 )));
73 };
74 object
75 .get(key)
76 .map(|value| {
77 T::from_setting(value).ok_or_else(|| {
78 RouterBuildError::Configuration(format!("setting `{key}` must be {}, got {value:?}", T::EXPECTED,))
79 })
80 })
81 .transpose()
82}
83
84pub fn parse_settings_json(json: &[u8]) -> aws_smithy_types::Document {
94 let mut tokens = aws_smithy_json::deserialize::json_token_iter(json).peekable();
95 let document = aws_smithy_json::deserialize::token::expect_document(&mut tokens)
96 .expect("codegen emits well-formed settings JSON");
97 assert!(tokens.next().is_none(), "codegen emits a single settings JSON document");
98 document
99}