Есть ли способ включить двоичные или текстовые файлы в библиотеку 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]);
}