Это на самом деле очень просто, но приводит к некоторым потенциальным проблемам. Во-первых, мы должны иметь дело с чем-то. Мы хотим загрузить дерево объектов из файла или проанализировать это во время выполнения?
99% времени, для людей достаточно разбора при загрузке в static ref
,так что я собираюсь дать вам это решение;В конце я укажу вам на «другую» версию, но это требует много дополнительной работы и зависит от домена.
Макрос (потому что он должен быть макросом)Вы ищете, чтобы иметь возможность включить файл во время компиляции находится в стандартной библиотеке: std::include_str!
. Как следует из названия, он берет ваш файл во время компиляции и генерирует из него &'static str
для использования. Затем вы можете делать с ним все, что захотите (например, анализировать его).
Оттуда можно просто использовать lazy_static!
для генерации static ref
к нашему JSON Value
(или к чему бы то ни было, на что вы решите пойти) для каждой используемой части программы. В вашем случае, например, это может выглядеть так:
const GAME_JSON:&str = include_str!("my/file.json");
#[derive(Serialize, Deserialize, Debug)]
struct Game {
name: String
}
lazy_static! {
static ref GAMES:Vec<Game> = serde_json::from_str(&GAME_JSON).unwrap();
}
При этом вам необходимо помнить о двух вещах:
- Это будет массово увеличивает размер файла, так как
&str
не сжимается никоим образом. Рассмотрим gzip - Вам нужно беспокоиться об обычных проблемах, связанных с многопоточным доступом к одному и тому же
static ref
, но, поскольку он не является изменяемым, вам действительно нужно беспокоиться только о его части
Другой способ требует динамической генерации ваших объектов во время компиляции с использованием proc-macro
. Как уже говорилось, я бы не рекомендовал этого, если у вас действительно нет действительно дорогих начальных затрат при анализе этого JSON;большинство людей этого не сделают, и в прошлый раз у меня это было, когда я имел дело с глубоко вложенными JSON-файлами с несколькими ГБ.
Ящики, на которые вы хотели обратить внимание: proc_macro2
и syn
для кодапоколения;остальное очень похоже на то, как вы бы написали обычный метод.