我正在尝试将 JSON 解析为一个具有chrono::DateTime
字段的结构。JSON 以自定义格式保存时间戳,我为其编写了反序列化器。
我如何连接两者并使用它来工作#[serde(deserialize_with)]
?
我正在使用NaiveDateTime
更简单的代码
extern crate serde;
extern crate serde_json;
use serde::Deserialize;
extern crate chrono;
use chrono::NaiveDateTime;
fn from_timestamp(time: &String) -> NaiveDateTime {
NaiveDateTime::parse_from_str(time, "%Y-%m-%dT%H:%M:%S.%f").unwrap()
}
#[derive(Deserialize, Debug)]
struct MyJson {
name: String,
#[serde(deserialize_with = "from_timestamp")]
timestamp: NaiveDateTime,
}
fn main() {
let result: MyJson =
serde_json::from_str(r#"{"name": "asdf", "timestamp": "2019-08-15T17:41:18.106108"}"#)
.unwrap();
println!("{:?}", result);
}
Run Code Online (Sandbox Code Playgroud)
我收到三个不同的编译错误:
error[E0308]: mismatched types
--> src/main.rs:11:10
|
11 | #[derive(Deserialize, Debug)]
| ^^^^^^^^^^^ expected reference, found type parameter …
Run Code Online (Sandbox Code Playgroud) 我需要在运行时构建一个 json 对象。现在,只是一个简单的 {"key": "stringvalue"} 对象。但每个键/值对必须添加到循环中。
这看起来非常简单/基本,但我没有找到任何好的示例或文档。我终于设法让一些东西发挥作用,但它似乎太复杂了,不是正确的方法。
任何人都可以发布一个工作示例吗?
我试图将JSON反序列化为包含可选字段的结构authorization
.JSON可能包含也可能不包含此字段.如果确实包含该字段,我正在进行自定义反序列化hyper::header::Authorization<hyper::header::Scheme>
.因为Authorization
需要泛型类型Scheme
,我需要(正如我写的那样)在我的struct上包含泛型类型.
所有的测试都通过了,但最后一个(没有授权字段的de_json_none
JSON )是语义上的怪异,因为我必须使用一个明确的类型(如图所示或者)来定位变量,这两个都没有任何意义.数据,尽管从Rust的角度来看完全有效.Scheme
Bearer
Basic
很清楚为什么会这样,但这是我不想要的东西,我不知道如何修复.
我想编写一个Rocket处理程序,它只Authorization<Bearer>
通过设置数据类型来匹配包含类型授权字段的数据Headers<Bearer>
.目前,它还会匹配根本没有该字段的数据.我也陷入困境,没有明确的方法来特别按类型调用缺少字段的数据.
我在寻找如何重构这个代码,以反映这一事实的建议Headers
确实有三个不同的,相互排斥的化身(Basic
,Bearer
和None
).也许我应该想在这里做点什么?
extern crate hyper;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
use hyper::header::{Authorization, Header, Raw, Scheme};
use serde::{Deserialize, Deserializer};
#[derive(Debug, Deserialize, PartialEq)]
struct Headers<S>
where
S: Scheme + 'static,
{
#[serde(deserialize_with = "auth_header", default = "no_auth")]
authorization: Option<Authorization<S>>,
#[serde(rename = ":path")]
path: String,
}
fn …
Run Code Online (Sandbox Code Playgroud) MVCE:
use std::collections::HashMap;
use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;
use serde; // 1.0.85
use serde::de::{self, MapAccess, Visitor}; // 1.0.85
use serde_derive::Deserialize; // 1.0.85
use toml; // 0.4.10
use void::Void; // 1.0.2
// See: https://serde.rs/string-or-struct.html
fn string_or_struct<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: serde::Deserialize<'de> + FromStr<Err = Void>,
D: serde::Deserializer<'de>,
{
// This is a Visitor that forwards string types to T's `FromStr` impl and
// forwards map types to T's `Deserialize` impl. The `PhantomData` is to
// …
Run Code Online (Sandbox Code Playgroud) 我有一个复杂的 JSON 文件,我只想从中提取一个值。我可以定义所有struct
s 并Deserialize
在所有这些s 上派生,但我只想编写一些手动代码来提取那个值。该SERDE文档,坦率地说,只是让我感到困惑。
我的 JSON 内容具有以下布局:
{
"data": [
{
"hostname": "a hostname"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找通过进入导航到的值data
,然后获取数组的第一个元素,并获取hostname
.
在 Haskell 中,我会这样做:
{
"data": [
{
"hostname": "a hostname"
}
]
}
Run Code Online (Sandbox Code Playgroud)
Serde 的等价物是什么?
我知道可用于未知 JSON 的 JSON 值。
我拥有的是一个大部分结构化的 JSON 对象,如下所示:
{
"error": [],
"result": {
"NAME_X": {
"prop_one": "something",
"prop_two": "something",
"decimals": 1,
"more_decimals": 2
},
"NAME_A": {
"prop_one": "test",
"prop_two": "sdfsdf",
"decimals": 2,
"more_decimals": 5
},
"ARBITRARY": {
"prop_one": "something else",
"prop_two": "blah",
"decimals": 3,
"more_decimals": 6
}
}
Run Code Online (Sandbox Code Playgroud)
因此,具有字段 prop_one、prop_two、decimals 和 more_decimals 的内部对象具有清晰的结构,但外部名称字段/键(NAME_X、NAME_A、ARBITRARY)事先未知。
解析此问题的最直接方法是什么,以便我可以在内部结构上使用强类型变量/反序列化?我还需要捕获那些未知的名称字段。
我有一个由其他枚举组成的枚举,类似于以下内容(serde
为简洁起见,省略了派生和注释):
enum Main {
A(SubA),
B(SubB),
}
enum SubA { X1, X2, X3 }
enum SubB { Y1, Y2, Y3 }
Run Code Online (Sandbox Code Playgroud)
我希望能够用来serde
反序列化诸如“X1”或“Y3”之类的字符串,并分别自动返回 aMain::A(SubA::X1)
或Main::B(SubB::Y3)
。
我知道它serde
支持#[serde(transparent)]
新类型样式结构上的属性,这可以做我喜欢的事情。但是,它似乎仅适用于结构或枚举级别,而不适用于枚举变体级别。有没有一种方法可以自动获得我正在寻找的行为?我可以确保任何包含的子枚举中的任何变体名称都不会重叠。
除了希望保持 Rust 2018 稳定之外,我对我的项目没有其他限制,并且我愿意接受任何有帮助的板条箱建议。
我遇到一个有趣的问题。由于某种原因,serde 无法chrono::DateTime<Utc>
从与序列化格式相同的字符串中反序列化对象(但如果我用它保存变量,它就会这样做):
use chrono; // 0.4.11
use serde_json; // 1.0.48
fn main() {
let date = chrono::Utc::now();
println!("{}", date);
let date_str = serde_json::to_string(&date).unwrap();
println!("{}", date_str);
let parsed_date: chrono::DateTime<chrono::Utc> = serde_json::from_str(&date_str).unwrap();
println!("{}", parsed_date);
assert_eq!(date, parsed_date);
let date = "2020-03-28T16:29:04.644008111Z";
let _: chrono::DateTime<chrono::Utc> = serde_json::from_str(&date).unwrap();
}
Run Code Online (Sandbox Code Playgroud)
这是游乐场链接
哪个输出:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.01s
Running `target/debug/playground`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: integer `2020`, expected a formatted …
Run Code Online (Sandbox Code Playgroud) 我从外部 API 收到毫秒时间戳作为 JSON 字符串属性。
{"time":"1526522699918"}
Run Code Online (Sandbox Code Playgroud)
使用 Serde 将毫秒时间戳解析为字符串的最佳方法是什么?
该ts_milliseconds
选项使用整数毫秒时间戳,但在使用字符串时会引发错误。
示例 - Rust 游乐场
{"time":"1526522699918"}
Run Code Online (Sandbox Code Playgroud)
错误信息:
Error("invalid type: string \"1526522699918\", expected a unix timestamp in milliseconds", line: 1, column: 23)'
Run Code Online (Sandbox Code Playgroud) 我正在使用 Rust 编写 REST API,我的 Flutter 客户端定义如下实体:
class WordDefinition {
String type;
String name;
List<String> values;
WordDefinition({
this.type,
this.name,
this.values,
});
}
Run Code Online (Sandbox Code Playgroud)
客户端用作type
实体字段名称。在 Dart 中它工作正常,但在服务器端 Rust 我无法像这样定义字段名称:
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
pub struct WordDefinition {
pub type: String,
pub text: String,
pub translations: Vec<String>,
}
Run Code Online (Sandbox Code Playgroud)
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
pub struct WordDefinition {
pub type: String,
pub text: String,
pub translations: Vec<String>,
}
Run Code Online (Sandbox Code Playgroud)
我应该怎么做才能避免 Rust 关键字冲突?是否可以type
在 Rust 中使用这样的方式定义实体名称?