xslt-transducer — техническое описание проекта
1. Назначение и амбиция
xslt-transducer — суверенная (с нуля, без FFI к чужим
движкам) реализация семейства языков XPath / XQuery /
XSLT на Rust. Ставка: иметь собственный движок
XML-трансформаций как алгебраическое ядро (“XML-pivot”), не завися от
Saxon (Java/GraalVM) и не ограничиваясь XPath 1.0, который покрывают
существующие Rust-крейты.
Зачем именно своё (подтверждается census-отчётом проекта): в
экосистеме Rust нет чистой реализации XPath 2.0+.
sxd-xpath — это XPath 1.0 (последнее обновление 2018),
libxml — FFI-обёртка над C-библиотекой libxml2. Ниша
“эргономичный, поддерживаемый pure-Rust движок XPath 3.1/4.0” пуста —
проект целится в неё.
Архитектурная амбиция (из doc-комментария движка): движок строится на
алгебраическом базисе из 4 примитивов
{ε, ⊕, φ, Δ} (пустота, конкатенация,
отображение/фильтр, рекурсия по дереву), над которыми надстраиваются
производные операции, а уже над ними — полный XPath. Целевой уровень —
XPath 4.0 (надмножество 3.1: добавлены
otherwise, pipeline-оператор, строковые шаблоны,
focus-функции, sequence-стрелки, method-вызовы и 50+ новых функций).
Формальная база описана в проектных документах по алгебре XPath, DSS и
схем (суммарно ~640 КБ заметок).
2. Архитектура (подпроекты)
Workspace из 4 крейтов:
| Крейт | Роль | Зрелость |
|---|---|---|
| xpath-core | Сам движок: лексер → парсер → AST → desugar в алгебру → эвалуатор + библиотека функций + модель данных XDM + система типов + XSD-схемы | основной, зрелый |
| xpath-harness | Прогон официального W3C-корпуса QT3/QT4: парсер каталога тестов, модель тест-кейса с логикой зависимостей/пропусков, проверка ассертов, параллельный запуск (rayon) | рабочий инструмент |
| xpath-census | Статистический инвентарь: сканирует корпуса тестов, считает частоту функций/осей/операторов/фич, чтобы приоритизировать реализацию. Это НЕ отчёт pass/fail | вспомогательный |
| dss-core | Отдельный, более ранний прототип XSLT-трансформации: алгебраическая модель XML “DSS” (свободный моноид Item’ов), parse/serialize/transform/парсер stylesheet | ранний прототип |
xpath-core — внутреннее устройство
Модули: lexer, parser, ast,
desugar, eval, functions,
xdm, types, derived,
axes, primitives, error,
schema.
- lexer.rs (88 КБ, ~167 видов токенов) — ручной токенайзер.
- parser.rs (354 КБ, 89 функций
parse_*) — ручной рекурсивный спуск на всю грамматику XPath/XQuery, включая XQuery FLWOR, prolog, объявления функций. - ast.rs (31 объявление struct/enum) — типизированное дерево выражений.
- desugar.rs (35 КБ) — понижение синтаксиса в
CompiledExprнад 4 примитивами. - eval.rs (408 КБ, 104 функции) — эвалуатор;
запускается с 256 МБ стеком, т.к. глубоко вложенные выражения дают
взаимно-рекурсивный
eval(). - functions.rs (802 КБ, ~698 ветвей диспетчеризации
по имени функции) — встроенная библиотека функций
fn:/xs:/map:/array:/math:XPath/XQuery 3.1 + часть 4.0. - xdm.rs (46 КБ, 10 типов) — модель данных XDM (XPath
Data Model): дерево с ареной (
XdmArena,XdmTree), последовательности, Item’ы. - types.rs (46 КБ) — система типов XDM (атомарные
типы, SequenceType, проверка
instance of/cast). - schema/ (lattice.rs 40 КБ, mapping.rs 73 КБ, validate.rs 86 КБ, types.rs 20 КБ) — поддержка XSD: решётка типов, маппинг, валидация. Это серьёзный объём.
Версии спецификаций: целится в XPath/XQuery 3.1 (полноценно) и 4.0 (фронтир, частично). Эвалуатор использует семантику XQuery 3.1; harness осознанно пропускает тесты с xpath-only-семантикой и со специфичной для XQuery 1.0/3.0 семантикой (см. §4).
3. Объём и зрелость (цифры)
| Метрика | Значение |
|---|---|
| LOC xpath-core (Rust, code) | 40 653 строк, 23 файла |
| LOC всего репозитория (Rust, code, без target) | ~49 358 строк, 43 файла |
Юнит-тестов в xpath-core (#[test]) |
293 |
Функций parse_* (рекурсивный спуск) |
89 |
| Ветвей диспетчеризации функций | ~698 |
| struct/enum/trait/fn в eval.rs | 3 struct, 3 enum, 4 impl, 104 fn |
Корпус тестов в проекте: QT3 61 МБ, QT4 63 МБ, XSLT 3.0 391 МБ, XSLT 4.0 326 МБ (всего ~840 МБ официальных W3C тест-данных).
Вердикт по зрелости (честно): xpath-core — это
рабочий, в значительной степени полный движок XPath/XQuery
3.1, заметно дальше «прототипа», но не
production. Аргументы: - ЗА зрелость: ~40 К LOC, 293
юнит-теста, ~98 % прохождения попыток на официальном W3C QT3, 0
паник/ошибок исполнения на 75 К тест-кейсов (см. §4) — движок
устойчив. - ПРОТИВ production: нет стабильного/документированного
публичного API (есть лишь
select/eval_string/test/parse),
нет бенчмарков производительности и фаззинга в дереве, осознанно не
реализованы XQuery-модули, static typing, schema-import, часть
collations, DTD-типы, методы сериализации (json/text/xhtml). - XSLT-слой
(dss-core) — ранний прототип (март 2026,
roundtrip-тесты XML, базовый transform), несопоставим по зрелости с
xpath-core. Полноценного XSLT-движка пока нет.
Одним словом: продвинутый рабочий движок XPath/XQuery 3.1, предпродакшен.
4. Тесты / conformance (реальные числа)
Прогон выполнен заново на release-бинаре harness,
--jobs 8. Это официальные W3C тест-сьюты
(QT3 = XPath/XQuery 3.1, QT4 = черновик XPath/XQuery 4.0).
QT3 (XPath / XQuery 3.1)
| Результат | Кол-во | % от всех |
|---|---|---|
| Total test-cases | 31 703 | 100 % |
| Passed | 30 139 | 95.1 % |
| Failed | 674 | 2.1 % |
| Skipped | 890 | 2.8 % |
| Errors (паники/краши) | 0 | 0.0 % |
Прохождение от попыток (без пропущенных): 30 139 / 30 813 = 97.8 %.
QT4 (XPath / XQuery 4.0, черновик)
| Результат | Кол-во | % от всех |
|---|---|---|
| Total test-cases | 43 288 | 100 % |
| Passed | 29 970 | 69.2 % |
| Failed | 1 775 | 4.1 % |
| Skipped | 11 543 | 26.7 % |
| Errors | 0 | 0.0 % |
Прохождение от попыток (без пропущенных): 29 970 / 31 745 = 94.4 %. Низкий «сырой» процент QT4 объясняется тем, что 4.0 — движущийся фронтир: 26.7 % пропущено (нереализованные 4.0-фичи, XQuery, static typing), а провалы — это новый синтаксис 4.0, который парсер ещё не разбирает.
Что пропускается (важно для честности)
Процент считается по поддерживаемому подмножеству. Harness осознанно
пропускает: xpath-only-тесты (движок на семантике XQuery), тесты только
для XQuery 1.0/3.0, а также фичи: typedData,
staticTyping, serialization,
infoset-dtd, xpath-1.0-compatibility,
non_empty_sequence_collection, schema-import-наборы.
Где провалы (категории «got:»)
QT3, 674 провала: доминирует 554 = parse
error (XPST) — почти все на крае синтаксиса (включая негативные
тесты на коды ошибок, где наш код ошибки не совпал). Дальше длинный
хвост по ~3–13 шт.:
FORG/FODC/FOER (динамические
ошибки аргументов, fn:error), lax-валидация схемы
(__validate_lax__), отдельные collation, несколько
расхождений значений. Единой крупной функциональной дыры
нет — здоровый профиль.
QT4, 1 775 провалов: в основном (а) новый синтаксис
4.0, который парсер не берёт (614 XPST + сотни «unexpected token»), и
(б) необязательные EXPath-модули, которых нет: bin:
(бинарный модуль, ~25 функций) и file: (файловый модуль) —
суммарно сотни кейсов; плюс предложенная ось
preceding-or-self. То есть провалы QT4 — это
экспериментальный край и опциональные расширения, а не дефекты ядра.
5. Чем ценно для работодателя (демонстрируемые навыки)
- Парсеры / формальные языки. Ручной лексер (~167 токенов) и рекурсивный спуск (89 функций) на всю грамматику XPath + XQuery (FLWOR, prolog, объявления функций) — без генераторов парсеров. Понижение в промежуточное представление (desugar) над минимальным алгебраическим базисом из 4 примитивов — нетривиальный язык-дизайн.
- Compliance к большой спецификации. Доказанная работа против официального W3C QT3/QT4: построен полноценный conformance-harness (парсер каталога, модель зависимостей, движок ассертов 75 КБ, параллельный прогон), 75 К тест-кейсов прогоняются без единой паники. Это редкий и убедительный для CTO артефакт — измеримое качество, а не слова.
- Rust на сложном домене. ~40 К LOC, арена-аллокатор
для дерева XDM, управление стеком (256 МБ под рекурсивный eval),
rustc-hash,bitvec,rust_decimal,fancy-regex,quick-xml— без unsafe-FFI к чужим движкам. - Система типов и XSD. ~220 КБ кода на решётку типов
XDM, проверку
instance of/cast/treat as, валидацию по схеме — реализация теории типов на практике. - Инженерная честность / приоритизация по данным. Отдельный census-инструмент измеряет реальную частоту фич в корпусе, чтобы строить движок «от 95 % реальных выражений», а не наугад.
Главный тезис для собеседования: «Своя реализация XPath/XQuery 3.1 на Rust, ~98 % прохождения официального W3C-теста на поддерживаемом подмножестве, 0 крашей на 75 000 тест-кейсов; цель — XPath 4.0, частично реализовано».
Приложение: где меряно, а где оценено
- Меряно (факт): все LOC, счётчики struct/fn, числа conformance QT3/QT4 (свежий прогон release-бинаря), категории провалов.
- Оценено по коду (не запускалось): вердикт
«предпродакшен» и список нереализованного (XQuery-модули, static typing,
перф/фаззинг) — вывод из структуры и skip-логики, не из отдельного
аудита. Зрелость
dss-core(XSLT) оценена по размеру/датам/тестам, отдельно не прогонялась.dss-coreи census-цифры самого движка (DSS) не верифицировались прогоном.
Контакты
- Email: splinter.rat.pro@gmail.com
- Телефон: +7 (999) 815-22-92
- Telegram: @Splinter_Rat