Skip to main content

qubit_codec/
form_urlencoded_codec.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! `application/x-www-form-urlencoded` text codec.
11
12use crate::percent_codec::{
13    percent_decode_bytes,
14    percent_encode_bytes,
15};
16use crate::{
17    CodecError,
18    CodecResult,
19    Decoder,
20    Encoder,
21};
22
23/// Encodes and decodes `application/x-www-form-urlencoded` text fragments.
24#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
25pub struct FormUrlencodedCodec;
26
27impl FormUrlencodedCodec {
28    /// Creates a form-url-encoded codec.
29    ///
30    /// # Returns
31    /// Form URL encoded codec.
32    pub fn new() -> Self {
33        Self
34    }
35
36    /// Encodes text, using `+` for spaces.
37    ///
38    /// # Parameters
39    /// - `text`: Text to encode.
40    ///
41    /// # Returns
42    /// Form-url-encoded text.
43    pub fn encode(&self, text: &str) -> String {
44        percent_encode_bytes(text.as_bytes(), true)
45    }
46
47    /// Decodes text, treating `+` as space.
48    ///
49    /// # Parameters
50    /// - `text`: Text to decode.
51    ///
52    /// # Returns
53    /// Decoded UTF-8 text.
54    ///
55    /// # Errors
56    /// Returns [`CodecError`] when an escape is malformed or decoded bytes are
57    /// not valid UTF-8.
58    pub fn decode(&self, text: &str) -> CodecResult<String> {
59        String::from_utf8(percent_decode_bytes(text, true)?).map_err(CodecError::from)
60    }
61}
62
63impl Encoder<str> for FormUrlencodedCodec {
64    type Error = CodecError;
65    type Output = String;
66
67    /// Encodes text, using `+` for spaces.
68    fn encode(&self, input: &str) -> Result<Self::Output, Self::Error> {
69        Ok(FormUrlencodedCodec::encode(self, input))
70    }
71}
72
73impl Decoder<str> for FormUrlencodedCodec {
74    type Error = CodecError;
75    type Output = String;
76
77    /// Decodes form-url-encoded text.
78    fn decode(&self, input: &str) -> Result<Self::Output, Self::Error> {
79        FormUrlencodedCodec::decode(self, input)
80    }
81}