aws_sdk_s3/endpoint_lib/
substring.rs
1use crate::endpoint_lib::diagnostic::DiagnosticCollector;
8
9pub(crate) fn substring<'a>(input: &'a str, start: usize, stop: usize, reverse: bool, e: &mut DiagnosticCollector) -> Option<&'a str> {
18 if start >= stop {
19 e.capture(Err("start > stop"))?;
20 }
21 if !input.is_ascii() {
22 e.capture(Err("the input to substring was not ascii"))?;
23 }
24 if input.len() < stop {
25 e.capture(Err("the input was too short"))?;
26 }
27 let (effective_start, effective_stop) = if !reverse {
28 (start, stop)
29 } else {
30 (input.len() - stop, input.len() - start)
31 };
32 Some(&input[effective_start..effective_stop])
33}
34
35#[cfg(all(test, feature = "gated-tests"))]
36mod test {
37 use super::*;
38 use proptest::proptest;
39
40 #[test]
41 fn substring_forwards() {
42 assert_eq!(substring("hello", 0, 2, false, &mut DiagnosticCollector::new()), Some("he"));
43 assert_eq!(substring("hello", 0, 0, false, &mut DiagnosticCollector::new()), None);
44 assert_eq!(substring("hello", 0, 5, false, &mut DiagnosticCollector::new()), Some("hello"));
45 assert_eq!(substring("hello", 0, 6, false, &mut DiagnosticCollector::new()), None);
46 }
47
48 #[test]
49 fn substring_backwards() {
50 assert_eq!(substring("hello", 0, 2, true, &mut DiagnosticCollector::new()), Some("lo"));
51 assert_eq!(substring("hello", 0, 0, true, &mut DiagnosticCollector::new()), None);
52 assert_eq!(substring("hello", 0, 5, true, &mut DiagnosticCollector::new()), Some("hello"))
53 }
54
55 #[test]
57 fn substring_unicode() {
58 let mut collector = DiagnosticCollector::new();
59 assert_eq!(substring("a🐱b", 0, 2, false, &mut collector), None);
60 assert_eq!(
61 format!("{}", collector.take_last_error().expect("last error should be set")),
62 "the input to substring was not ascii"
63 );
64 }
65
66 use proptest::prelude::*;
67 proptest! {
68 #[test]
69 fn substring_no_panics(s in any::<String>(), start in 0..100usize, stop in 0..100usize, reverse in proptest::bool::ANY) {
70 substring(&s, start, stop, reverse, &mut DiagnosticCollector::new());
71 }
72
73 #[test]
74 fn substring_correct_length(s in r"[\x00-\xFF]*", start in 0..10usize, stop in 0..10usize, reverse in proptest::bool::ANY) {
75 prop_assume!(start < s.len());
76 prop_assume!(stop < s.len());
77 prop_assume!(start < stop);
78 if let Some(result) = substring(&s, start, stop, reverse, &mut DiagnosticCollector::new()) {
79 assert_eq!(result.len(), stop - start);
80 }
81
82 }
83 }
84}