mirror of
https://github.com/Brandon-Rozek/website.git
synced 2024-11-25 01:26:30 -05:00
New post
This commit is contained in:
parent
1e96cdae1b
commit
8a6f05fdc5
1 changed files with 103 additions and 0 deletions
103
content/blog/modifying-json-in-rust.md
Normal file
103
content/blog/modifying-json-in-rust.md
Normal file
|
@ -0,0 +1,103 @@
|
|||
---
|
||||
title: "Modifying JSON in Rust"
|
||||
date: 2024-08-03T07:59:15-07:00
|
||||
draft: false
|
||||
tags: []
|
||||
math: false
|
||||
medium_enabled: false
|
||||
---
|
||||
|
||||
For my new role, I've been learning Rust. I don't know why I didn't learn it earlier, I enjoy it so much that I decided to power my [toots](/toots) page with it.
|
||||
|
||||
When I query my toots, I receive a JSON response like the following:
|
||||
|
||||
```json
|
||||
[{"id": "112581869512127927", ..., "content": "...",}, ...]
|
||||
```
|
||||
|
||||
Some parts of the JSON response changes quite frequently. Since I [archive](https://brandonrozek.com/blog/archiving-toots/) the changes, I want to strip out the highly dynamic information before saving it off to a file.
|
||||
|
||||
```rust
|
||||
let mut json_response: serde_json::Value = serde_json::from_str("...")
|
||||
.expect("JSON parse error");
|
||||
```
|
||||
|
||||
In order to modify this variable, we need to have some knowledge of it's structure. I'll show in this post how to modify our JSON data given whether we're working with a JSON array or a JSON object.
|
||||
|
||||
## `serde_json::Value::Array`
|
||||
|
||||
Our example JSON starts off as an array, so let's extract that out:
|
||||
|
||||
```rust
|
||||
let json_array = json_response
|
||||
.as_array_mut()
|
||||
.expect("Expected JSON Array");
|
||||
```
|
||||
|
||||
The `as_array_mut` says to interpret the `json_response` variable as an array. The `mut` component is important for us to be able to edit the data in place without making copies.
|
||||
|
||||
The `as_array_mut` method returns an option type. Calling `.expect(...)` on it will cause the program to crash if it isn't indeed an array. We can alternatively perform some error handling:
|
||||
|
||||
```rust
|
||||
if let Some(json_array) = json_response.as_array_mut() {
|
||||
// Do something with json_array
|
||||
} else {
|
||||
// Error handling here
|
||||
}
|
||||
```
|
||||
|
||||
Though I'll assume that you're following best practices and not discuss more about error handling in this post.
|
||||
|
||||
Our variable `json_array` has type `&mut Vec<serde_json::Value>`which means we can do things like add another element to said array.
|
||||
|
||||
```rust
|
||||
let new_element = serde_json::Value::from(1);
|
||||
json_array.push(new_element);
|
||||
```
|
||||
|
||||
We can also remove the last element of the array if it exists
|
||||
|
||||
```rust
|
||||
json_array.pop()
|
||||
```
|
||||
|
||||
## `serde_json::Value::Object`
|
||||
|
||||
Within the array, we have a list of objects. Let us grab the first element as an example:
|
||||
|
||||
```rust
|
||||
let first_item = json_array.get_mut(0).unwrap();
|
||||
```
|
||||
|
||||
In order to be able to modify the data, we use the `get_mut` method. This, like before, returns an option if it doesn't exist. We can call `unwrap` on it to get access to the data or panic if the element doesn't exist.
|
||||
|
||||
The variable `first_item` has type `serde_json::Value`. To interpret this as an object, we need to call `as_object_mut`.
|
||||
|
||||
```rust
|
||||
let first_item_obj = first_item.as_object_mut().unwrap();
|
||||
```
|
||||
|
||||
Now our variable `first_item_obj` has type `&mut Map<String, serde_json::Value>`.
|
||||
|
||||
We can remove any fields that we don't think is important
|
||||
|
||||
```rust
|
||||
first_item_obj.remove("bot");
|
||||
```
|
||||
|
||||
Add any fields we want
|
||||
|
||||
```rust
|
||||
let new_key = "PoweredBy".to_string();
|
||||
let new_value = serde_json::Value::from("Rust");
|
||||
toot.insert(new_key, new_value);
|
||||
```
|
||||
|
||||
Renaming a field is the combination of the last two:
|
||||
|
||||
```rust
|
||||
let toot_date = toot.remove("created_at")
|
||||
.expect("Missing created_at");
|
||||
toot.insert("date".to_string(), toot_date);
|
||||
```
|
||||
|
Loading…
Reference in a new issue