Есть ли способ включить двоичные или текстовые файлы в библиотеку Rust?
Я пытаюсь создать библиотеку, и я хочу включить в нее некоторые двоичные (или текстовые) файлы, которые будут иметь данные, которые будут проанализированы во время выполнения.
мое намерение состоит в том, чтобы иметь контроль над этими файлами, постоянно их обновлять и менять версию библиотеки в каждом обновлении.
это возможно через груз? Если да, то как я могу получить доступ к этим файлам из моей библиотеки?
обходной путь, о котором я думал, должен включать некоторые .rs
файлы со структурами и / или константы типа &str
который будет хранить данные, но я нахожу его уродливым.
EDIT:
Я изменил принятый ответ на тот, который больше подходит для моего случая, однако взгляните на Shepmaster это как это может быть более подходящим в вашем случае.
2 ответов
отказ от ответственности: я упомянул об этом в комментарии, но позвольте мне повторить здесь, так как это дает мне больше места для разработки.
как сказал Шепмастер, можно включить текст или двоичный дословный текст в библиотеку/исполняемый файл Rust с помощью include_bytes!
и include_str!
макросы.
в вашем случае, однако, я бы этого избежал. Отложив разбор содержимого во время выполнения:
- вы позволяете строить дефектный артефакт.
- вы нести (больше) время выполнения накладные расходы (время работы парсера).
- вы несете (больше) накладные расходы (синтаксический анализ кода).
Rust признает эту проблему и предлагает несколько механизмов генерации кода, предназначенных для преодоления этих ограничений:
- макросы: если логика может быть закодирована в макрос, то она может быть включена в исходный файл непосредственно
- Плагины: питание макросов, которые могут кодировать любую произвольную логику и создавать сложные код (см.
regex!
) -
build.rs
: независимый "сценарий ржавчины", опережающий собственно компиляцию, роль которой заключается в создании.rs
файлы
в вашем случае build.rs
скрипт звучит как хорошо подходит:
- перемещая код разбора туда, вы доставляете более легкий артефакт
- разбирая заранее, вы доставляете более быстрый артефакт
- путем разбора заранее, вы поставляете правильное артефакт!--19-->
результат вашего разбора может быть закодирован по-разному, от функций до статики (возможно lazy_static!
), as build.rs
может генерировать любой допустимый код ржавчины.
вы можете увидеть, как использовать build.rs
на грузовая документация; вы найдете там, как интегрировать его с грузом и как создавать файлы (и многое другое).
на include_bytes!
макрос, кажется, близок к тому, что вы хотите. Это только дает вам ссылку на массив байтов, поэтому вам придется делать любой разбор, начиная с этого:
static HOST_FILE: &'static [u8] = include_bytes!("/etc/hosts");
fn main() {
let host_str = std::str::from_utf8(HOST_FILE).unwrap();
println!("Hosts are:\n{}", &host_str[..42]);
}
если у вас есть содержимое UTF-8, вы можете использовать include_str!
, как указал Бенджамин Линдли:
static HOST_FILE: &'static str = include_str!("/etc/hosts");
fn main() {
println!("Hosts are:\n{}", &HOST_FILE[..42]);
}