May 2025
Accessing JSON Data with Unknown Keys In Rust
Introduction
These are just snippets for now. The most recent is at the top.
use anyhow::Result;
use anyhow::anyhow;
use dirs::home_dir;
use serde_json::Value;
use std::fs;
use std::path::PathBuf;
fn main() -> Result<()> {
extract_cards()
}
fn extract_card(card: &Value) -> Result<()> {
let card_name = get_card_name(card)?;
dbg!(card_name);
Ok(())
}
fn extract_cards() -> Result<()> {
let input_data = load_json()?;
input_data
.as_object()
.ok_or(anyhow!("Could not load cards object"))?
.get_key_value("cards")
.ok_or(anyhow!("Could not get cards"))?
.1
.as_array()
.ok_or(anyhow!("Could not get cards array"))?
.iter()
.for_each(|card| {
let _ = extract_card(card);
});
Ok(())
}
fn get_card_name(card: &Value) -> Result<String> {
Ok(
card
.as_object()
.ok_or(anyhow!("Could not get card as object"))?
.get_key_value("name")
.ok_or(anyhow!("Could not get name"))?
.1
.to_string(),
)
}
fn json_path() -> PathBuf {
home_dir()
.unwrap()
.join("workshop")
.join("mtg-data")
.join("scryfall")
.join("current")
.join("oracle-cards--sample.json")
}
fn load_json() -> Result<Value> {
println!("Loading JSON...");
let raw_input = fs::read_to_string(json_path()).unwrap();
let wrapped_input = format!(r#"{{ "cards": {} }}"#, raw_input);
let data = serde_json::from_str(wrapped_input.as_str())?;
println!("Finished Loading JSON...");
Ok(data)
}Prior Examples
impl Book {
pub fn get_words_of_kind(&self, kind: &str) -> Result<Vec<String>> {
Ok(self.letters[0].words
.as_object()
.expect("asdf")
.values()
.filter_map(|x| {
match x["meanings"].as_array() {
Some(meanings) => {
meanings.iter().take(1).find_map(|meaning| {
match meaning["speech_part"].as_str() {
Some(speech_part) => {
if kind == speech_part {
Some(x["word"].as_str()?.to_string())
} else {
None
}
},
None => None
}
})
}
None => None
}
}).collect()
)
}
}---
[dependencies]
anyhow = "1.0.98"
serde_json = "1.0.140"
---
use anyhow::Result;
use std::path::PathBuf;
use std::fs;
use serde_json::{Value};
struct Book {
letters: Vec<Letter>
}
struct Letter {
words: Value
}
impl Book {
pub fn word_data(&self) -> Result<Vec<&Value>> {
let x: &Vec<&Value> = &self.letters[0].words.as_object().expect("asdf").values().map(|x| x).collect();
dbg!(x);
Ok(vec![])
}
}
fn main() -> Result<()> {
let book = load_data()?;
book.word_data()?;
//dbg!(book?.adjectives()?.len());
Ok(())
}
pub fn load_data() -> Result<Book> {
let files = get_files_in_dir(&PathBuf::from("data-letters"))?;
let book = Book {letters: files.iter().map(|f| {
let content = fs::read_to_string(f).unwrap();
let letter =
Letter{
words: serde_json::from_str(&content).unwrap()
};
letter
}).collect()};
Ok(book)
}
pub fn get_files_in_dir(dir: &PathBuf) -> Result<Vec<PathBuf>> {
let files = fs::read_dir(dir)?
.into_iter()
.filter(|p| {
if p.as_ref().unwrap().path().is_file() {
true
} else {
false
}
})
.map(|p| p.as_ref().unwrap().path())
.filter(|p| {
!p.file_name().unwrap().to_str().unwrap().starts_with(".")
})
.collect();
Ok(files)
}
let x = &self.letters[0].words.as_object().expect("asdf").values().for_each(|x| {dbg!(x); ()});end of line