- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个问题类似
How do I implement a trait I don't own for a type I don't own?
我为 Date 编写了一个序列化程序,使用文档中描述的机制,我的模块包装了一个序列化函数
pub mod my_date_format {
use chrono::{Date, NaiveDate, Utc};
use serde::{self, Deserialize, Deserializer, Serializer};
const SERIALIZE_FORMAT: &'static str = "%Y-%m-%d";
pub fn serialize<S>(date: &Date<Utc>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = format!("{}", date.format(SERIALIZE_FORMAT));
serializer.serialize_str(&s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Date<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDate::parse_from_str(s.as_str(), SERIALIZE_FORMAT)
.map_err(serde::de::Error::custom)
.map(|x| {
let now = Utc::now();
let date: Date<Utc> = Date::from_utc(x, now.offset().clone());
date
})
}
}
那么我可以这样做:
struct MyStruct {
#[serde(with = "my_date_format")]
pub start: Date<Utc>,
}
问题是如果我将序列化的东西包装在其他类型(它们本身是可序列化的)中,我会收到错误:
#[serde(with = "my_date_format")]
pub dates: Vec<Date<Utc> // this won't work now since my function doesn't serialize vectors
pub maybe_date: Option<Date<Utc>>> // won't work
pub box_date: Box<Date<Utc>> // won't work...
在使用我自己的序列化程序时如何获得提供的实现?
最佳答案
最直接的方法,是作为 question you linked谈论,即创建一个新类型,换行 Date<Utc>
,并实现 Serialize
和 Deserialize
对于那种类型。
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Debug)]
struct FormattedDate(Date<Utc>);
impl Serialize for FormattedDate {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// If you implement `Deref`, then you don't need to add `.0`
let s = format!("{}", self.0.format(SERIALIZE_FORMAT));
serializer.serialize_str(&s)
}
}
impl<'de> Deserialize<'de> for FormattedDate {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDate::parse_from_str(s.as_str(), SERIALIZE_FORMAT)
.map_err(serde::de::Error::custom)
.map(|x| {
let now = Utc::now();
let date: Date<Utc> = Date::from_utc(x, now.offset().clone());
Self(date)
// or
// date.into()
})
}
}
为了让生活更轻松,您可以实现
Deref
和
DerefMut
然后使用
FormattedDate
透明地表现得好像您正在使用
Date<Utc>
直接地。
use std::ops::{Deref, DerefMut};
impl Deref for FormattedDate {
type Target = Date<Utc>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for FormattedDate {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
同样你可以实现
From
和
Into
, 这样您就可以轻松地在
FormattedDate
之间转换和
Date<Utc>
.
impl From<Date<Utc>> for FormattedDate {
fn from(date: Date<Utc>) -> Self {
Self(date)
}
}
impl Into<Date<Utc>> for FormattedDate {
fn into(self) -> Date<Utc> {
self.0
}
}
现在,您提供的所有示例都易于使用:
#[derive(Serialize, Deserialize, Debug)]
struct MyStruct {
date: FormattedDate,
dates: Vec<FormattedDate>,
opt_date: Option<FormattedDate>,
boxed_date: Box<FormattedDate>,
}
fn main() {
let s = MyStruct {
date: Utc::now().date().into(),
dates: std::iter::repeat(Utc::now().date().into()).take(4).collect(),
opt_date: Some(Utc::now().date().into()),
boxed_date: Box::new(Utc::now().date().into()),
};
let json = serde_json::to_string_pretty(&s).unwrap();
println!("{}", json);
}
哪个输出:
{
"date": "2020-12-13",
"dates": [
"2020-12-13",
"2020-12-13",
"2020-12-13",
"2020-12-13"
],
"opt_date": "2020-12-13",
"boxed_date": "2020-12-13"
}
关于rust - 如何为我不拥有的类型实现 serde 并让它支持复合/wrapper/collection 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65279642/
我假设 jls 中描述的转换是根据优先级排序的。首先具有更高的优先级。 jls 因此我解决了 Boxing 比 Unboxing 具有更高的优先级。我决定检验这个假设。 研究以下代码: public
谁能解释一下我的 html 设计出了什么问题 Profile 问题是 div 标签(#profile wrapper)正在增加它的 margin top,如果我增加 #intro w
下面的完整代码示例(已成功编译)是我的问题的简化且稍微做作的示例。 NatPair 是一对 Nat ,我想使用函数 Num 将二进制 NatPair 操作逐点“提升”到 lift_binary_op_
给定以下函数: public void convertToWrapper(long[] longsToConvert) { } 和 public void convertToPrimitiv
我有这样的代码: class Base { } class Derived : Base { } class Wrapper { public T Value { get; } pub
我正在安装 SonarQube v5.0。 我正在运行 Windows Server 2012 64 位(虚拟操作系统)、Java 1.8 64 位和 SonarQube windows-x86-64
我正在为我的一个组件编写测试用例,该组件具有路由器(使用 withrouter)。我收到错误 wrapper.find is not a function。基本要求是需要检查我的渲染中是否存在标签,还
如何制作 在不改变结构的情况下,内部包装器比包装器本身更大? HTML CSS .page { width: 100%; height: 400px; bor
为了引导 Gradle-Wrapper,我需要从需要 HTTP Basic-Auth 的 Artifactory 中提取 Gradle 发行版。我的构建环境无法访问外部世界 - 这被公司代理阻止。我的
我正在构建一个Spring-Boot应用程序(2.1.4.RELEASE),并且正在使用它创建一个Gradle Wrapper gradle clean wrapper 我的gradle版本是5.4
以下代码取自这篇文章:How to create Scala swing wrapper classes with SuperMixin? import scala.swing._ import ja
我想同时使用 Boost.Asio 的 strand 和 prioritized wrapper。 在我编写代码之前,我阅读了以下信息: Boost asio priority and strand
Android Studio 的 Gradle 选项到底有什么区别: Android Studio->Preferences->Gradle 使用默认的gradle wrapper(推荐)和使用可定制
目前我有一个设置宽度为 1240 像素的包装器。可以想象,这意味着我页面中心的 1240 像素始终被包装器覆盖。 我还有一张宽度为 3160 像素的图像(1920 像素的图像大小,在中间切割并由 12
这只是一个练习,但我无法弄清楚其中的歧义: private static void flipFlop(String str, int i, Integer iRef) { System.out.pri
所以我现在正在编写我的网站,我正在使用两个 div 在背景中创建某种渐变,其中 div#bg1 为灰色,div#bg2 为深灰色。但是当我添加包装器 div 时,bg1 和 bg2 仍然遵循包装器的顶
已解决:必须 float #main div,并对结构进行许多其他重大更改。但致命一击是 float 的。 可以在 http://thepremium.ca/amodestblog 查看有问题的网站
操作系统:Windows 8.1 Visual Studio 高级版 2013 我有一个复杂的 MVC 应用程序,我已经运行了多年。我能够毫无问题地在调试中运行应用程序。然而,就在今天下午,当我尝试发
在带有 python 3.6.8 的 Ubuntu 18.04 上,尝试安装 Airflow。当我运行airflow initdb命令时,抛出以下错误 Traceback (most recent c
我将我的 Android Studio 升级到 2.3 版,然后开始出现此错误: Error:org.gradle.wrapper.WrapperExecutor.forProjectDirector
我是一名优秀的程序员,十分优秀!