proptest_http_message/request_line/target/
mod.rs

1//! HTTP request target strategies.
2
3use std::{num::NonZero, ops::RangeInclusive};
4
5use proptest::{prelude::Strategy, prop_oneof};
6
7use crate::request_line::target::{
8  absolute_form::AbsoluteForm, authority_form::AuthorityForm, origin_form::OriginForm,
9};
10
11pub mod absolute_form;
12pub mod asterisk_form;
13pub mod authority_form;
14pub mod components;
15pub mod origin_form;
16
17/// All valid HTTP request target forms.
18#[derive(Debug)]
19pub enum RequestTarget {
20  Absolute(AbsoluteForm),
21  Origin(OriginForm),
22  Authority(AuthorityForm),
23  Asterisk,
24}
25
26/// strategy for generating HTTP request target.
27///
28/// # Arguments
29/// * `max_label_count`: maximum label count to use for domain hosts in case of authority form,
30///   origin form and absolute form.
31/// * `max_segments`: maximum number of segments that compose the path in case of absolute form
32///   and origin form.
33/// * `query_count_range`: range of the number of queries to include in case of  absolute form
34///   and origin form.
35///
36/// # Returns
37/// [`RequestTarget`] and it representation.
38pub fn target(
39  max_label_count: usize,
40  max_segments: NonZero<usize>,
41  query_count_range: RangeInclusive<usize>,
42) -> impl Strategy<Value = (RequestTarget, String)> {
43  prop_oneof![
44    absolute_form::absolute(max_label_count, max_segments, query_count_range.clone())
45      .prop_map(|(absolute, repr)| (RequestTarget::Absolute(absolute), repr)),
46    origin_form::origin(max_segments, query_count_range)
47      .prop_map(|(origin, repr)| (RequestTarget::Origin(origin), repr)),
48    authority_form::authority(max_label_count)
49      .prop_map(|(authority, repr)| (RequestTarget::Authority(authority), repr)),
50    asterisk_form::asterisk().prop_map(|repr| (RequestTarget::Asterisk, repr)),
51  ]
52}
53
54#[cfg(test)]
55pub(super) mod tests {
56  use proptest::proptest;
57
58  use super::*;
59
60  pub(in super::super) fn target_asserts(target: &RequestTarget, repr: &str) {
61    match target {
62      RequestTarget::Absolute(absolute_form) => {
63        absolute_form::tests::absolute_asserts(absolute_form, repr);
64      }
65      RequestTarget::Origin(origin_form) => origin_form::tests::origin_asserts(origin_form, repr),
66      RequestTarget::Authority(authority_form) => {
67        authority_form::tests::authority_asserts(authority_form, repr);
68      }
69      RequestTarget::Asterisk => asterisk_form::tests::asterisk_asserts(repr),
70    }
71  }
72
73  proptest! {
74    #[test]
75    fn target_works((target, repr) in target(20, 50.try_into().unwrap(), 0..=20)) {
76      target_asserts(&target, &repr);
77    }
78  }
79}