1use crate::urlencode::BASE_SET;
10use aws_smithy_types::date_time::{DateTimeFormatError, Format};
11use aws_smithy_types::DateTime;
12use percent_encoding::AsciiSet;
13
14const GREEDY: &AsciiSet = &BASE_SET.remove(b'/');
15
16#[non_exhaustive]
18#[derive(Clone, Debug, Eq, PartialEq)]
19pub enum EncodingStrategy {
20 Default,
22 Greedy,
24}
25
26pub fn fmt_string<T: AsRef<str>>(t: T, strategy: EncodingStrategy) -> String {
28 let uri_set = if strategy == EncodingStrategy::Greedy {
29 GREEDY
30 } else {
31 BASE_SET
32 };
33 percent_encoding::utf8_percent_encode(t.as_ref(), uri_set).to_string()
34}
35
36pub fn fmt_timestamp(t: &DateTime, format: Format) -> Result<String, DateTimeFormatError> {
38 Ok(fmt_string(t.fmt(format)?, EncodingStrategy::Default))
39}
40
41#[cfg(test)]
42mod test {
43 use crate::label::{fmt_string, EncodingStrategy};
44 use http_02x::Uri;
45 use proptest::proptest;
46
47 #[test]
48 fn greedy_params() {
49 assert_eq!(fmt_string("a/b", EncodingStrategy::Default), "a%2Fb");
50 assert_eq!(fmt_string("a/b", EncodingStrategy::Greedy), "a/b");
51 }
52
53 proptest! {
54 #[test]
55 fn test_encode_request(s: String) {
56 let _: Uri = format!("http://host.example.com/{}", fmt_string(&s, EncodingStrategy::Default))
57 .parse()
58 .expect("all strings should be encoded properly");
59 let _: Uri = format!("http://host.example.com/{}", fmt_string(&s, EncodingStrategy::Greedy))
60 .parse()
61 .expect("all strings should be encoded properly");
62 }
63 }
64}