Skip to content

Instantly share code, notes, and snippets.

@hube12
Last active March 11, 2021 16:34
Show Gist options
  • Save hube12/c87ccd91c519560b4b1cdcefa2e534af to your computer and use it in GitHub Desktop.
Save hube12/c87ccd91c519560b4b1cdcefa2e534af to your computer and use it in GitHub Desktop.
// [dependencies]
// ron = "0.6.4"
// serde = { version = "1.0.60", features = ["serde_derive"] }
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use std::collections::HashMap;
fn option_remove_serialize<S,T:Serialize>(x: &Option<T>, s: S) -> Result<S::Ok, S::Error> where S: Serializer {
x.as_ref().unwrap().serialize(s)
}
fn is_empty_subject(x: &SubjectMapping) -> bool {
x.primary.is_none() && x.secondary.is_none()
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Game {
macros: HashMap<String, Macros>, // those macros are applied to the actions
#[serde(skip_serializing_if = "HashMap::is_empty")]
actions: HashMap<String, String>, // in this version the actions are not described for conciseness
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Macros {
#[serde(skip_serializing_if = "Option::is_none",serialize_with="option_remove_serialize")]
superseded: Option<String>, // this is the macros that is extended
#[serde(default,skip_serializing_if = "is_empty_subject")]
subject: SubjectMapping, // we want to force a subject even if the subject has no element
#[serde(skip_serializing_if = "Option::is_none",serialize_with="option_remove_serialize")]
action: Option<ActionMapping>, // we don't really care if there is an action
#[serde(default,skip_serializing_if = "Vec::is_empty")]
how: Vec<String>, // this is either empty or filled
}
#[derive(Debug, Deserialize, Serialize,Default)]
pub struct SubjectMapping {
#[serde(skip_serializing_if = "Option::is_none",serialize_with="option_remove_serialize")]
primary: Option<String>,
#[serde(skip_serializing_if = "Option::is_none",serialize_with="option_remove_serialize")]
secondary: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ActionMapping {
#[serde(skip_serializing_if = "Option::is_none",serialize_with="option_remove_serialize")]
primary: Option<String>,
}
const GAME: &str = include_str!("../constants/game.ron");
#[test]
fn test_deserialize() {
use ron::from_str;
let r: Result<Game, _> = from_str(GAME);
dbg!(&r);
assert!(r.is_ok());
}
#[test]
fn test_reserialize() {
use ron::extensions::Extensions;
use ron::from_str;
let r: Game = from_str(GAME).expect("no issue on deserialization");
dbg!(&r);
use ron::ser::{PrettyConfig, to_string_pretty};
let pretty = PrettyConfig::new()
.with_separate_tuple_members(true)
.with_enumerate_arrays(false)
.with_extensions(Extensions::IMPLICIT_SOME)
.with_extensions(Extensions::UNWRAP_NEWTYPES);
let r = to_string_pretty(&r, pretty);
assert!(r.is_ok());
let r=r.unwrap();
print!("{}",r);
}
@hube12
Copy link
Author

hube12 commented Mar 11, 2021

game.ron

#![enable(implicit_some,unwrap_newtypes)]
(
    macros:{
       "defaults" : (
           action:()
       ),
       "hero" : (
           superseded: "defaults",
           subject: (
             primary: "hero",
             secondary: "paladin",
           ),
           action:(
             primary: "attack"
           ),
           how: ["sword","magic"],
       ),
    },
    actions:{}
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment