Rust パーセントエンコーディング

パーセントエンコーディング

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~
以外の文字を{%[hex]}*nの組み合わせに置き換える。
HTTPリクエストなどで送るときに必要。

fn urlencode(my_str: String) -> String {
    let unreservedchars =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~".to_string();
    let mut encoded = String::new();
    for c in my_str.chars() {
        match unreservedchars.find(c) {
            Some(_) => {
                encoded.push(c);
            }
            None => {
                let mut bytes = [0; 3];
                c.encode_utf8(&mut bytes);
                let percented = match c.len_utf8() {
                    1 => format!("%{:X}", bytes[0]),
                    2 => format!("%{:X}%{:X}", bytes[0], bytes[1]),
                    3 => format!("%{:X}%{:X}%{:X}", bytes[0], bytes[1], bytes[2]),
                    _ => "".to_string(),
                };
                encoded = format!("{}{}", encoded, percented);
            }
        }
    }
    encoded
}

こんな感じか(?)
あんまり速くないと思う。

しかし、reqwestのUrl structureを使えばqueryを組み立てるところまでやってくれることに書いてから気付いた。

    let mut url = Url::parse("https://www.google.co.jp").unwrap(); //ここはなんかのURLが必要。
    url.query_pairs_mut()
        .append_pair("hoge", "aaa")
        .append_pair("piyo", "あ")
        .append_pair("foo", "漢字")
        .append_pair("bar", "ß");
    println!("{:?}", url.query().unwrap());

結果

hoge=aaa&piyo=%E3%81%82&foo=%E6%BC%A2%E5%AD%97&bar=%C3%9F

文字コードはUTF8を利用しているのでUTF8で出る。

依存を見ると
f:id:katakanan:20180401041940p:plain
https://crates.io/crates/percent-encoding

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

マスタリングTCP/IP 入門編 第5版

マスタリングTCP/IP 入門編 第5版