verticopolis_engine/
identity.rs1use serde_json::{json, Value};
17
18use crate::canonical::canonical_json;
19use crate::catalog::{catalog_digest, CATALOG_VERSION};
20use crate::clock::GameMode;
21use crate::frame::FRAME_LAYOUT_VERSION;
22use crate::load::OLDEST_SAVE_VERSION;
23use crate::sim::SAVE_VERSION;
24
25pub const IDENTITY_SCHEMA: u32 = 1;
27
28pub const CRATE_NAME: &str = "verticopolis-engine";
30
31const UNREADABLE: &str = "unreadable";
35
36const COMPAT_RECORD: &str = include_str!("compat-record.json");
37
38fn compat_field(name: &str) -> String {
39 serde_json::from_str::<Value>(COMPAT_RECORD)
40 .ok()
41 .and_then(|v| v.get(name).and_then(Value::as_str).map(str::to_owned))
42 .unwrap_or_else(|| UNREADABLE.to_owned())
43}
44
45pub fn crate_version() -> String {
47 compat_field("crateVersion")
48}
49
50pub fn identity() -> Value {
52 json!({
53 "schema": IDENTITY_SCHEMA,
54 "crate": { "name": CRATE_NAME, "version": crate_version() },
55 "saveVersion": SAVE_VERSION,
56 "oldestSaveVersion": OLDEST_SAVE_VERSION,
57 "frameLayoutVersion": FRAME_LAYOUT_VERSION,
58 "catalogVersion": CATALOG_VERSION,
59 "catalogDigests": {
60 "classic": catalog_digest(GameMode::Classic),
61 "modern": catalog_digest(GameMode::Modern),
62 },
63 "lockDigest": compat_field("lockDigest"),
64 })
65}
66
67pub fn identity_json() -> String {
69 canonical_json(&identity())
70}
71
72#[cfg(test)]
73#[path = "identity_tests.rs"]
74mod tests;