如何在 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);
}