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}