Задача 1. Чтение, парсинг и анализ данных в Rust.
Тема проекта: Чтение, парсинг и анализ данных в Rust
Цели:
- Получить практические навыки написания кода с применением статического полиморфизма на основе трейтов.
- Реализовать несколько парсеров для разных видов данных и для создания идиоматичных многомодульных приложений.
Задание:
Разработать библиотеку (crate) для парсинга/сериализации/десериализации финансовых данных в несколько форматов и отдельный исполняемый cli (консольное приложение) crate, использующий данную библиотеку.
Поддерживаемые форматы (минимум для реализации):
- YPBankCsv - Таблица банковских операций.
- YPBankText - Текстовый формат описания списка операций.
- YPBankBin - Бинарное предоставление списка операций.
Детали задания
Необходимо реализовать три крейта.
Крейт Parser
Библиотека, обеспечивающая парсинг и сериализацию форматов. Реализации парсера должны использовать абстракции, предоставляемые стандартной библиотекой языка, чтобы обеспечить гибкость кода. Не следует жестко привязывать реализацию парсера к конкретному типу источника данных. Чтобы это сделать, используйте стандартные трейты ввода/вывода (в первую очередь Read для чтения и Write для записи), а не пишите отдельные реализаций для каждого источника (файла, stdin, массива байт и т.д.).
Пример:
struct YPBankBinRecord {
// Поля структуры, представляющей содержимое записи
}
impl YPBankBinRecord {
// Парсит из любого источника, реализующего трейт Read
pub fn from_read<R: std::io::Read>(r: &mut R) -> Result<Self> {
todo!()
}
// Записывает отчёт в любой приёмник, реализующий трейт Write
pub fn write_to<W: std::io::Write>(&mut self, writer: &mut W) -> Result<()> {
todo!()
}
}Использование трейтов позволяет избежать дублирования кода: не нужно реализовывать отдельные парсеры для файлов, stdin, буферов и т.п. Кроме того, сторонние крейты также могут предоставлять свои реализации этих трейтов.
CLI Converter
Консольное приложение, использующее функциональность парсеров из первого крейта. Парсеры крейта «парсер» принимают в качестве входа типы, удовлетворяющие трейту Read. CLI-приложение должно читать данные из файла и выводить результат в stdout. Для библиотеки ничего не меняется — она работает с абстракциями, определёнными в стандартной библиотеке, реализованными для типа File и доступными в любом Rust-приложении. За счёт статического полиморфизма (мономорфизации) в итоговый бинарник попадут только те реализации трейтов, которые реально используются.
Пример запуска утилиты:
ypbank_converter \
--input <input_file> \
--input-format <format> \
--output-format <format> \
> output_file.txtCLI Comparer
Консольное приложение, использующее функциональность парсеров из lib-крейта. CLI Comparer должен читать данные о транзакциях из двух файлов и сравнивать их. Входные файлы могут быть в любых форматах, которые поддерживаются парсерами из lib-крейта. В случае несовпадения, утилита должна сообщать какая транзакция не совпала.
Пример запуска утилиты:
ypbank_compare --file1 records_example.bin --format1 binary --file2 records_example.csv --format2 csv
# Output: The transaction records in 'records_example.bin' and 'records_example.csv' are identical.Требования к результатам работы
Общие требования к проекту
- Данные должны переводиться из любого из трёх поддерживаемых форматов в другой. Чтение и запись данных должны производиться за счёт трейтов Read и Write стандартной библиотеки.
- Код приложения должен быть размещён на GitHub.
- Реализации парсера должны использовать имеющиеся абстракции, поставляемые с языком для достижения гибкости кода. Не нужно делать реализации парсера в привязке к типу данных напрямую.
- Крейт для парсинга данных должен быть отдельным, а крейты для исполняемых файлов импортировать элементы из lib-крейта.
- Не использовать unwrap в крейтах.
- Реализовать понятные ошибки и корректно их отработать в коде.
- Публичные элементы крейта «Парсер» должны быть покрыты документацией.
- Код должен быть покрыт тестами.
Функциональные требования
Крейт «парсер» должен:
- Читать данные вышеупомянутых форматов.
- Записывать данные вышеупомянутых форматов.
- Возвращать понятные ошибки, если такие встречаются при парсинге.
Cli-приложение:
- Использует библиотеку «парсер» и предоставляет:
- Чтение из файла или stdin.
- Запись в файл или stdout.
- Опции формата ввода и вывода (—in-format и —out-format).
- Реализует функции, предоставляемые крейтом парсера.
CLI выступает в роли «прокси» между пользователем и библиотекой: оно вызывает методы парсеров (например, from_read и write_to) и обеспечивает маршрутизацию ввода/вывода между файловой системой и стандартными потоками. Поскольку парсеры работают с абстракциями Read/Write, для них нет различия между источниками/приёмниками данных.