aws_sdk_s3/endpoint_lib/
substring.rs

1// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
2/*
3 *  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *  SPDX-License-Identifier: Apache-2.0
5 */
6
7use crate::endpoint_lib::diagnostic::DiagnosticCollector;
8
9/// substring of `input`
10///
11/// > Note: this function only operates on ASCII input. If the input contains non-ASCII characters,
12/// > `None` will be returned.
13///
14/// - When `reverse` is false, indexes are evaluated from the beginning of the string
15/// - When `reverse` is true, indexes are evaluated from the end of the string (however, the result
16///   will still be "forwards" and `start` MUST be less than `end`.
17pub(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    // substring doesn't support unicode, it always returns none
56    #[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}