windmark 0.9.0

An elegant and highly performant async Gemini server framework
Documentation
#[derive(Clone, Default)]
pub struct Parameters(Vec<(String, String)>);

impl Parameters {
  pub(crate) fn from_parameters(parameters: &matchit::Params<'_, '_>) -> Self {
    Self(
      parameters
        .iter()
        .map(|(k, v)| (k.to_string(), v.to_string()))
        .collect(),
    )
  }

  pub(crate) fn from_lookup(
    parameters: &matchit::Params<'_, '_>,
    lookup: &str,
    original: &str,
    offsets: &[usize],
  ) -> Self {
    Self(
      parameters
        .iter()
        .map(|(name, value)| {
          // Matchit borrows from the lookup path. Percent decoding needs a
          // boundary map; ASCII case folding alone preserves byte offsets.
          let start = value.as_ptr().addr() - lookup.as_ptr().addr();
          let end = start + value.len();
          let (start, end) = if offsets.is_empty() {
            (start, end)
          } else {
            (offsets[start], offsets[end])
          };

          (name.to_owned(), original[start..end].to_owned())
        })
        .collect(),
    )
  }

  #[must_use]
  pub fn get(&self, key: &str) -> Option<&str> {
    self
      .0
      .iter()
      .find(|(k, _)| k == key)
      .map(|(_, v)| v.as_str())
  }

  #[must_use]
  pub const fn is_empty(&self) -> bool { self.0.is_empty() }

  pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
    self.0.iter().map(|(k, v)| (k.as_str(), v.as_str()))
  }
}