如何在 Rust 中使用 cookie 工厂进行序列化?
How to serialize using cookie-factory in Rust?
cookie-factory in Rust has no documentation on how to understand it. It just lists all the functions. I took a look at examples/http.rs 对此了解甚少。
我有以下结构:
pub struct DigestChallengeResponse {
pub username: String,
pub realm: Option<String>,
pub uri: Option<Url>,
pub nonce: Option<String>,
pub cnonce: Option<String>,
pub opaque: Option<String>,
pub stale: Option<bool>,
pub algorithm: Option<Algorithm>,
pub cnonce: i32,
pub qop: Option<Qop>,
pub response: String,
pub userhash: Option<bool>,
}
其中非标准类型实现 Display
我需要序列化成这个:
Authorization: Digest
username="488869477bf257147b804c45308cd62ac4e25eb717
b12b298c79e62dcea254ec",
realm="api@example.org",
uri="/doe.json",
algorithm=SHA-512-256,
nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK",
nc=00000001,
cnonce="NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v",
qop=auth,
response="ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d
6c861229025f607a79dd",
opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS",
userhash=true
首先,我真的需要 cookie-factory 来进行如此简单的序列化吗?我应该怎么做?
我看了一下do_gen
,这是主要的宏之一,但不明白它的作用:https://docs.rs/cookie-factory/0.3.2/cookie_factory/macro.do_gen.html
有 3 件事要做:
- 最简单的是为您的结构实现 Display
- Option 没有实现 Display,所以你必须定义你自己的 displayed trait 并实现你作为可选的每个类型
- Enum 也没有实现 Display。但实际上,我们有第三个库 strum 一个帮助您执行操作的助手。
所以,这是你的字符串化器:)
extern crate strum;
#[macro_use]
extern crate strum_macros;
use std::fmt;
#[derive(AsRefStr)]
enum Algorithm {
Sha512,
Sha256,
}
#[derive(AsRefStr)]
enum Qop {
Auth,
}
struct DigestChallengeResponse {
pub username: String,
pub realm: Option<String>,
pub uri: Option<String>,
pub nonce: Option<String>,
pub nc: Option<String>,
pub opaque: Option<String>,
pub stale: Option<bool>,
pub algorithm: Option<Algorithm>,
pub cnonce: Option<String>,
pub qop: Option<Qop>,
pub response: String,
pub userhash: Option<bool>,
}
trait DisplayOption {
fn to_string(&self) -> String;
}
impl DisplayOption for std::option::Option<String> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<Algorithm> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val.as_ref()),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<Qop> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val.as_ref()),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<bool> {
fn to_string(&self) -> String {
match self {
Some(val) => if *val {"true".to_string()} else {"false".to_string()},
_ => "".to_string()
}
}
}
impl fmt::Display for DigestChallengeResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"Digest
username={},
realm={},
uri={},
algorithm={},
nonce={},
nc={},
qop={},
response={},
opaque={},
userhash={},
stale={}
"
, self.username
, self.realm.to_string()
, self.uri.to_string()
, self.algorithm.to_string()
, self.nonce.to_string()
, self.nc.to_string()
, self.qop.to_string()
, self.response.to_string()
, self.opaque.to_string()
, self.userhash.to_string()
, self.stale.to_string()
)
}
}
fn main() {
let authorization = DigestChallengeResponse {
username: "488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec".to_string(),
realm: Some("api@example.org".to_string()),
uri: Some("/doe.json".to_string()),
algorithm: Some(Algorithm::Sha512),
nonce: Some("5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK".to_string()),
nc: Some("00000001".to_string()),
cnonce: Some("NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v".to_string()),
qop: Some(Qop::Auth),
response: "ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d6c861229025f607a79dd".to_string(),
opaque: Some("HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS".to_string()),
userhash: Some(true),
stale: Some(true),
};
println!("Authorization: {}", authorization);
}
cookie-factory in Rust has no documentation on how to understand it. It just lists all the functions. I took a look at examples/http.rs 对此了解甚少。
我有以下结构:
pub struct DigestChallengeResponse {
pub username: String,
pub realm: Option<String>,
pub uri: Option<Url>,
pub nonce: Option<String>,
pub cnonce: Option<String>,
pub opaque: Option<String>,
pub stale: Option<bool>,
pub algorithm: Option<Algorithm>,
pub cnonce: i32,
pub qop: Option<Qop>,
pub response: String,
pub userhash: Option<bool>,
}
其中非标准类型实现 Display
我需要序列化成这个:
Authorization: Digest
username="488869477bf257147b804c45308cd62ac4e25eb717
b12b298c79e62dcea254ec",
realm="api@example.org",
uri="/doe.json",
algorithm=SHA-512-256,
nonce="5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK",
nc=00000001,
cnonce="NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v",
qop=auth,
response="ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d
6c861229025f607a79dd",
opaque="HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS",
userhash=true
首先,我真的需要 cookie-factory 来进行如此简单的序列化吗?我应该怎么做?
我看了一下do_gen
,这是主要的宏之一,但不明白它的作用:https://docs.rs/cookie-factory/0.3.2/cookie_factory/macro.do_gen.html
有 3 件事要做:
- 最简单的是为您的结构实现 Display
- Option 没有实现 Display,所以你必须定义你自己的 displayed trait 并实现你作为可选的每个类型
- Enum 也没有实现 Display。但实际上,我们有第三个库 strum 一个帮助您执行操作的助手。
所以,这是你的字符串化器:)
extern crate strum;
#[macro_use]
extern crate strum_macros;
use std::fmt;
#[derive(AsRefStr)]
enum Algorithm {
Sha512,
Sha256,
}
#[derive(AsRefStr)]
enum Qop {
Auth,
}
struct DigestChallengeResponse {
pub username: String,
pub realm: Option<String>,
pub uri: Option<String>,
pub nonce: Option<String>,
pub nc: Option<String>,
pub opaque: Option<String>,
pub stale: Option<bool>,
pub algorithm: Option<Algorithm>,
pub cnonce: Option<String>,
pub qop: Option<Qop>,
pub response: String,
pub userhash: Option<bool>,
}
trait DisplayOption {
fn to_string(&self) -> String;
}
impl DisplayOption for std::option::Option<String> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<Algorithm> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val.as_ref()),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<Qop> {
fn to_string(&self) -> String {
match self {
Some(val) => format!("{}", val.as_ref()),
_ => "".to_string()
}
}
}
impl DisplayOption for std::option::Option<bool> {
fn to_string(&self) -> String {
match self {
Some(val) => if *val {"true".to_string()} else {"false".to_string()},
_ => "".to_string()
}
}
}
impl fmt::Display for DigestChallengeResponse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"Digest
username={},
realm={},
uri={},
algorithm={},
nonce={},
nc={},
qop={},
response={},
opaque={},
userhash={},
stale={}
"
, self.username
, self.realm.to_string()
, self.uri.to_string()
, self.algorithm.to_string()
, self.nonce.to_string()
, self.nc.to_string()
, self.qop.to_string()
, self.response.to_string()
, self.opaque.to_string()
, self.userhash.to_string()
, self.stale.to_string()
)
}
}
fn main() {
let authorization = DigestChallengeResponse {
username: "488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec".to_string(),
realm: Some("api@example.org".to_string()),
uri: Some("/doe.json".to_string()),
algorithm: Some(Algorithm::Sha512),
nonce: Some("5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK".to_string()),
nc: Some("00000001".to_string()),
cnonce: Some("NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v".to_string()),
qop: Some(Qop::Auth),
response: "ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d6c861229025f607a79dd".to_string(),
opaque: Some("HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS".to_string()),
userhash: Some(true),
stale: Some(true),
};
println!("Authorization: {}", authorization);
}