Custom deserialization of an array or array of values using Serde [duplicate]
This question already has an answer here:
How can I deserialize JSON with a top-level array using Serde?
1 answer
I would like to build a custom deserializer to deserialize an array of arrays of values into a Vec<Child>
where I have already written a custom serde deserializer to parse an array of values into a Child
.
One idea would be to add a customer deserializer for a Vec<Child>
directly but I was wondering whether a more elegant solution would exist.
As an illustration I'm trying to make something like the below but with field array
in Parent instead of single
.
extern crate serde_json; // 1.0.32
extern crate serde; // 1.0.80
#[macro_use] extern crate serde_derive;
use serde::de::{Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug, Deserialize)]
struct Parent {
#[serde(deserialize_with = "parse_child")]
single: Child,
//#[serde(deserialize_with = "parse_child")]
//array: Vec<Child>,
}
#[derive(Default, Debug, Deserialize)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn parse_child<'de, D>(deserializer: D) -> Result<Child, D::Error>
where
D: Deserializer<'de>,
{
struct ChildParser;
impl<'de> Visitor<'de> for ChildParser
{
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
println!("In custom deserializer");
let mut child = Child { ..Default::default() };
let tmp = seq.next_element::<u64>()?;
if let Some(a) = tmp {
child.a = a;
};
let tmp = seq.next_element::<f32>()?;
if let Some(b) = tmp {
child.b = b;
};
let tmp = seq.next_element::<usize>()?;
if let Some(c) = tmp {
child.c = c;
};
Ok(child)
}
}
deserializer.deserialize_any(ChildParser{})
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child : Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:?}", &child);
let parent_data = r#"{"single": [49, 11.75, 0]}"#;
let parent : Parent = serde_json::from_str(parent_data).expect("to be able to deserialize it");
println!("Parent = {:?}", &parent);
}
Link to a playground
Sample input I want to deserialize: [[49, 11.75, 0], [42, 9, 1]]
rust serde
marked as duplicate by Shepmaster
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 15 '18 at 15:27
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
How can I deserialize JSON with a top-level array using Serde?
1 answer
I would like to build a custom deserializer to deserialize an array of arrays of values into a Vec<Child>
where I have already written a custom serde deserializer to parse an array of values into a Child
.
One idea would be to add a customer deserializer for a Vec<Child>
directly but I was wondering whether a more elegant solution would exist.
As an illustration I'm trying to make something like the below but with field array
in Parent instead of single
.
extern crate serde_json; // 1.0.32
extern crate serde; // 1.0.80
#[macro_use] extern crate serde_derive;
use serde::de::{Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug, Deserialize)]
struct Parent {
#[serde(deserialize_with = "parse_child")]
single: Child,
//#[serde(deserialize_with = "parse_child")]
//array: Vec<Child>,
}
#[derive(Default, Debug, Deserialize)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn parse_child<'de, D>(deserializer: D) -> Result<Child, D::Error>
where
D: Deserializer<'de>,
{
struct ChildParser;
impl<'de> Visitor<'de> for ChildParser
{
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
println!("In custom deserializer");
let mut child = Child { ..Default::default() };
let tmp = seq.next_element::<u64>()?;
if let Some(a) = tmp {
child.a = a;
};
let tmp = seq.next_element::<f32>()?;
if let Some(b) = tmp {
child.b = b;
};
let tmp = seq.next_element::<usize>()?;
if let Some(c) = tmp {
child.c = c;
};
Ok(child)
}
}
deserializer.deserialize_any(ChildParser{})
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child : Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:?}", &child);
let parent_data = r#"{"single": [49, 11.75, 0]}"#;
let parent : Parent = serde_json::from_str(parent_data).expect("to be able to deserialize it");
println!("Parent = {:?}", &parent);
}
Link to a playground
Sample input I want to deserialize: [[49, 11.75, 0], [42, 9, 1]]
rust serde
marked as duplicate by Shepmaster
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 15 '18 at 15:27
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
That much better but your question is still unclear. We don't know if you want to be able to deserializer#"{"single": [49, 11.75, 0]}"#
orr#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.
– Stargateur
Nov 13 '18 at 16:27
2
What trouble you withlet parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?
– Stargateur
Nov 13 '18 at 16:34
add a comment |
This question already has an answer here:
How can I deserialize JSON with a top-level array using Serde?
1 answer
I would like to build a custom deserializer to deserialize an array of arrays of values into a Vec<Child>
where I have already written a custom serde deserializer to parse an array of values into a Child
.
One idea would be to add a customer deserializer for a Vec<Child>
directly but I was wondering whether a more elegant solution would exist.
As an illustration I'm trying to make something like the below but with field array
in Parent instead of single
.
extern crate serde_json; // 1.0.32
extern crate serde; // 1.0.80
#[macro_use] extern crate serde_derive;
use serde::de::{Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug, Deserialize)]
struct Parent {
#[serde(deserialize_with = "parse_child")]
single: Child,
//#[serde(deserialize_with = "parse_child")]
//array: Vec<Child>,
}
#[derive(Default, Debug, Deserialize)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn parse_child<'de, D>(deserializer: D) -> Result<Child, D::Error>
where
D: Deserializer<'de>,
{
struct ChildParser;
impl<'de> Visitor<'de> for ChildParser
{
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
println!("In custom deserializer");
let mut child = Child { ..Default::default() };
let tmp = seq.next_element::<u64>()?;
if let Some(a) = tmp {
child.a = a;
};
let tmp = seq.next_element::<f32>()?;
if let Some(b) = tmp {
child.b = b;
};
let tmp = seq.next_element::<usize>()?;
if let Some(c) = tmp {
child.c = c;
};
Ok(child)
}
}
deserializer.deserialize_any(ChildParser{})
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child : Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:?}", &child);
let parent_data = r#"{"single": [49, 11.75, 0]}"#;
let parent : Parent = serde_json::from_str(parent_data).expect("to be able to deserialize it");
println!("Parent = {:?}", &parent);
}
Link to a playground
Sample input I want to deserialize: [[49, 11.75, 0], [42, 9, 1]]
rust serde
This question already has an answer here:
How can I deserialize JSON with a top-level array using Serde?
1 answer
I would like to build a custom deserializer to deserialize an array of arrays of values into a Vec<Child>
where I have already written a custom serde deserializer to parse an array of values into a Child
.
One idea would be to add a customer deserializer for a Vec<Child>
directly but I was wondering whether a more elegant solution would exist.
As an illustration I'm trying to make something like the below but with field array
in Parent instead of single
.
extern crate serde_json; // 1.0.32
extern crate serde; // 1.0.80
#[macro_use] extern crate serde_derive;
use serde::de::{Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug, Deserialize)]
struct Parent {
#[serde(deserialize_with = "parse_child")]
single: Child,
//#[serde(deserialize_with = "parse_child")]
//array: Vec<Child>,
}
#[derive(Default, Debug, Deserialize)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn parse_child<'de, D>(deserializer: D) -> Result<Child, D::Error>
where
D: Deserializer<'de>,
{
struct ChildParser;
impl<'de> Visitor<'de> for ChildParser
{
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
println!("In custom deserializer");
let mut child = Child { ..Default::default() };
let tmp = seq.next_element::<u64>()?;
if let Some(a) = tmp {
child.a = a;
};
let tmp = seq.next_element::<f32>()?;
if let Some(b) = tmp {
child.b = b;
};
let tmp = seq.next_element::<usize>()?;
if let Some(c) = tmp {
child.c = c;
};
Ok(child)
}
}
deserializer.deserialize_any(ChildParser{})
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child : Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:?}", &child);
let parent_data = r#"{"single": [49, 11.75, 0]}"#;
let parent : Parent = serde_json::from_str(parent_data).expect("to be able to deserialize it");
println!("Parent = {:?}", &parent);
}
Link to a playground
Sample input I want to deserialize: [[49, 11.75, 0], [42, 9, 1]]
This question already has an answer here:
How can I deserialize JSON with a top-level array using Serde?
1 answer
rust serde
rust serde
edited Nov 13 '18 at 14:04
Boris
asked Nov 13 '18 at 11:56
BorisBoris
216210
216210
marked as duplicate by Shepmaster
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 15 '18 at 15:27
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Shepmaster
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 15 '18 at 15:27
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
That much better but your question is still unclear. We don't know if you want to be able to deserializer#"{"single": [49, 11.75, 0]}"#
orr#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.
– Stargateur
Nov 13 '18 at 16:27
2
What trouble you withlet parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?
– Stargateur
Nov 13 '18 at 16:34
add a comment |
1
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
That much better but your question is still unclear. We don't know if you want to be able to deserializer#"{"single": [49, 11.75, 0]}"#
orr#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.
– Stargateur
Nov 13 '18 at 16:27
2
What trouble you withlet parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?
– Stargateur
Nov 13 '18 at 16:34
1
1
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
That much better but your question is still unclear. We don't know if you want to be able to deserialize
r#"{"single": [49, 11.75, 0]}"#
or r#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.– Stargateur
Nov 13 '18 at 16:27
That much better but your question is still unclear. We don't know if you want to be able to deserialize
r#"{"single": [49, 11.75, 0]}"#
or r#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.– Stargateur
Nov 13 '18 at 16:27
2
2
What trouble you with
let parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?– Stargateur
Nov 13 '18 at 16:34
What trouble you with
let parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?– Stargateur
Nov 13 '18 at 16:34
add a comment |
2 Answers
2
active
oldest
votes
I would implement this as:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Or more concisely:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding thetransparent
example to the linked duplicate.
– Shepmaster
Nov 15 '18 at 15:27
add a comment |
I'm not sure if this is what you want but using the doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child: Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:#?}", child);
let parent_data = r#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}
Thanks @Stargateur indeed I just needed to implement manuallyDeserialize
forChild
instead of deriving it
– Boris
Nov 13 '18 at 19:12
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would implement this as:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Or more concisely:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding thetransparent
example to the linked duplicate.
– Shepmaster
Nov 15 '18 at 15:27
add a comment |
I would implement this as:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Or more concisely:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding thetransparent
example to the linked duplicate.
– Shepmaster
Nov 15 '18 at 15:27
add a comment |
I would implement this as:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Or more concisely:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
I would implement this as:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Or more concisely:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
answered Nov 13 '18 at 17:40
dtolnaydtolnay
3,46711633
3,46711633
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding thetransparent
example to the linked duplicate.
– Shepmaster
Nov 15 '18 at 15:27
add a comment |
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding thetransparent
example to the linked duplicate.
– Shepmaster
Nov 15 '18 at 15:27
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
Thanks a lot @dtolnay that's a super neat way to do it indeed. I didn't know (or understand) serde could deserialize struct from arrays directly
– Boris
Nov 13 '18 at 19:23
I'd suggest adding the
transparent
example to the linked duplicate.– Shepmaster
Nov 15 '18 at 15:27
I'd suggest adding the
transparent
example to the linked duplicate.– Shepmaster
Nov 15 '18 at 15:27
add a comment |
I'm not sure if this is what you want but using the doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child: Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:#?}", child);
let parent_data = r#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}
Thanks @Stargateur indeed I just needed to implement manuallyDeserialize
forChild
instead of deriving it
– Boris
Nov 13 '18 at 19:12
add a comment |
I'm not sure if this is what you want but using the doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child: Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:#?}", child);
let parent_data = r#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}
Thanks @Stargateur indeed I just needed to implement manuallyDeserialize
forChild
instead of deriving it
– Boris
Nov 13 '18 at 19:12
add a comment |
I'm not sure if this is what you want but using the doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child: Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:#?}", child);
let parent_data = r#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}
I'm not sure if this is what you want but using the doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child: Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:#?}", child);
let parent_data = r#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}
answered Nov 13 '18 at 16:25
StargateurStargateur
8,43241848
8,43241848
Thanks @Stargateur indeed I just needed to implement manuallyDeserialize
forChild
instead of deriving it
– Boris
Nov 13 '18 at 19:12
add a comment |
Thanks @Stargateur indeed I just needed to implement manuallyDeserialize
forChild
instead of deriving it
– Boris
Nov 13 '18 at 19:12
Thanks @Stargateur indeed I just needed to implement manually
Deserialize
for Child
instead of deriving it– Boris
Nov 13 '18 at 19:12
Thanks @Stargateur indeed I just needed to implement manually
Deserialize
for Child
instead of deriving it– Boris
Nov 13 '18 at 19:12
add a comment |
1
@Stargateur there you go. Any idea on how I could solve this?
– Boris
Nov 13 '18 at 14:05
That much better but your question is still unclear. We don't know if you want to be able to deserialize
r#"{"single": [49, 11.75, 0]}"#
orr#"[[49, 11.75, 0], [42, 9, 1]]"#
or both.– Stargateur
Nov 13 '18 at 16:27
2
What trouble you with
let parent: Vec<Child> = serde_json::from_str(parent_data).unwrap()
?– Stargateur
Nov 13 '18 at 16:34