Parsing and storing json records

Hi,

Problem i am struggling with is the following :

What i have is an input stream of json records, values of which i need to process and save in a local hashmap. example of the json input:

let json = r#"
            {
                "16457-18516":[
                    0,289,5,[
                        67,84,5,4,4,84,84,65,88,71,65,65,67,60,65,65,71,84,65
                    ]
                ]
            }
        "#;
    

HashMap into which json needs to parsed into has essentially the same structure:

extern crate serde;
use serde::{Serialize, Deserialize};
use std::collections::HashMap;


fn main (){
 
   let json = r#"
            {
                "16457-18516":[
                    0,289,5,[
                       67,84,5,4,4,84,84,65,88,71,65,65,67,60,65,65,71,84,65
                    ]
                ]
            }
        "#;
    
    let mut hashmap: HashMap<String,(usize,usize,usize,Vec<u8>)> = HashMap::new();
    hashmap  = serde_json::from_str(&json).unwrap();

So far so good. But what i need to do is ti preprocess the Vec 67,84,5,4,4,84,84,65,88,71,65,65,67,60,65,65,71,84,65 such that each value is incremented by 42 and then stashed into my hash map.

What would be the way to go here ? loading values into hashmap first and then trying to change the values turned out the be quite complicated. What would be a simpler alternative to this ? Any examples ?

Thank you

A

How were you trying to increment the values before?

I would do something like this:

type Record = (usize, usize, usize, Vec<u8>);
let mut hashmap: HashMap<String, Record> = serde_json::from_str(&json).unwrap();

hashmap
    .values_mut()
    .for_each(|(_, _, _, items)| items.iter_mut().for_each(|n| *n += 42));

Also keep in mind that incrementing a u8 by 42 will probably cause some elements to overflow. If this is important for you (and it probably should be), you could deserialize into a Vec<Wrapping<u8>> instead of Vec<u8> so the += operator handles overflows automatically. Alternatively, you could do the incrementing with *n = n.wrapping_add(42) or *n = n.saturating_add(42), depending on the desired overflow behaviour.

2 Likes

Depending on what those numbers to be incremented by 42 actually are, it may be a good idea to make a newtype for them:

struct Mytype(u8);

type Record = (usize, usize, usize, Vec<Mytype>); 

Then you can implement Deserialize for that type in such a way that you check that the number are small enough and add 42 before returning a Mytype (which would have a better name, depending on what it's actually used for).

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.