xdoc-rs 0.1.0

Declarative XML engine for Rust
Documentation

xdoc

Motor XML declarativo en Rust.

La fuente de verdad del alcance actual es plan_libreria_xml_generica_rust.md. El proyecto se limita por ahora al motor XML generico; no incluye dominios como UBL, DIAN, SOAP, HL7, CDA o SAML.

Aunque el plan usa nombres tipo xdoc-core para separar responsabilidades, este repositorio implementara la libreria como una sola crate Rust importable llamada xdoc, organizada por carpetas internas. El package publico para crates.io sera xdoc-rs, porque xdoc y xml-builder ya estan ocupados.

Excepciones permitidas: xdoc-macros existe exclusivamente para la proc-macro xml!, y xdoc-cli existe como crate separado para publicar o instalar el binario xdoc. El motor XML sigue viviendo en xdoc-rs/xdoc y no depende del CLI.

Direccion de API: la experiencia objetivo debe parecerse a Leptos, pero para XML. Es decir: componentes Rust, props tipadas, children, composicion declarativa y una macro ergonomica que produzca XML estructurado y deterministico.

Limitaciones actuales del MVP

[] La validacion de nombres XML es conservadora: acepta nombres ASCII (A-Z, a-z, _, digitos, - y . segun posicion) y no implementa todavia el rango Unicode completo de XML 1.0. [] Los namespaces reservados xml y xmlns tienen reglas explicitas, pero la compatibilidad XML fina seguira ampliandose con fixtures y pruebas adicionales. [] xml!, query, transform, schema y signature son superficies del motor generico; no incluyen dominios. [] signature tiene base inicial de algoritmos, SHA-256, base64, IDs, Canonical XML 1.1 sin comentarios, XMLDSig enveloped, XAdES-BES, XAdES-EPES, XAdES Baseline-B, timestamp XAdES-T configurable, providers deterministicos de pruebas, provider RSA-SHA256 real con llaves en memoria, carga explicita y ergonomica PKCS#12/PFX, metadatos X.509 genericos para issuer/serial/cadena, signed properties tipadas para descripcion de politica/roles, perfiles de validacion configurables y XadesSigner ergonomico para orquestar pasos opcionales T/LT/LTA. [] Las politicas de firma EPES/Baseline-B son configurables desde capas superiores y no pertenecen a ningun dominio del motor. [] El CLI xdoc vive en el package xdoc-cli y ofrece comandos de inspeccion/desarrollo para formatear, compactar, parsear, consultar, validar contratos propios y canonicalizar XML.

Alcance

El alcance llega hasta estos modulos/carpetas del motor:

[] src/core/ [] src/writer/ [] src/builder/ [] src/component/ [] src/parser/ [] src/macros/ [] src/query/ [] src/transform/ [] src/schema/ [] src/signature/ [] src/security/ [] src/testing/ [] crates/xdoc-cli/ [] xdoc-macros solo si xml! requiere proc-macro.

Estado de modulos

Modulo Estado Alcance actual
core MVP implementado Modelo de nombres, namespaces, errores y arbol Document con salida deterministica como base del motor.
builder MVP implementado Construccion ergonomica de documentos, elementos y fragments sin manipular NodeId directamente.
component MVP implementado Componentes Rust con props tipadas, children explicitos, opciones y colecciones, usable sin macro.
writer MVP implementado Serializacion compacta y pretty deterministica, preservando texto significativo, CDATA y mixed content.
parser MVP implementado Parsing seguro hacia Document, con limites configurables, rechazo de DTD/entidades externas por defecto y soporte basico de namespaces.
macros / xdoc-macros MVP implementado Macro xml! sobre builder/component con elementos, atributos, namespaces, comentarios, expresiones, componentes y compile tests.
query MVP implementado Subset tipo XPath para paths absolutos, descendientes, atributos, text(), aliases de namespace y predicados simples por atributo. No es XQuery.
transform MVP implementado Templates programaticos XML a XML sobre query, parametros, condicionales, repeat y limites de expansion. No es XSLT.
schema MVP implementado Contratos propios del motor: required, cardinality, tipos simples, enum y reglas custom. No es XSD completo.
security MVP implementado Politicas y limites compartidos por parser, query y transform con defaults seguros.
signature Parcial Algoritmos, URIs XMLDSig/XMLENC, SHA-256, base64, resolucion de IDs, Canonical XML 1.0/1.1 sin comentarios, XMLDSig enveloped con referencias y ubicacion configurables, XAdES-BES, XAdES-EPES, Baseline-B, XAdES-T, validation data, archive timestamps verificables, providers deterministicos, provider RSA-SHA256 real con llaves PEM/DER o PKCS#12/PFX en memoria, Pkcs12SigningCredentials para cargar .pfx/.p12 por ruta/password y usarlo como provider, metadatos X.509 genericos para issuer/serial/cadena, signed properties tipadas para descripcion de politica, SPUserNotice y SignerRole, SignatureValidationProfile para requisitos estrictos genericos, y XadesSigningOptions para ejecutar flujos T/LT/LTA desde una API de alto nivel. No incluye TSA RFC 3161 productiva ni validacion legal de certificados todavia.
testing Base implementada Helpers reutilizables para fixtures, golden comparisons con diff legible, roundtrip parser/writer, property tests de escaping y harness inicial de fuzzing para parser.
cli (xdoc-cli) MVP implementado Binario xdoc con format, compact, parse, query, validate, canonicalize y alias validate-wellformed para inspeccion basica del motor.

Limites conocidos

La macro xml! es azucar sobre el builder y no parsea XML externo en runtime. El texto raw sigue la tokenizacion de Rust, los props de componentes deben ser identificadores simples, las declaraciones de namespace deben ser literales string y los componentes usan sintaxis explicita <{ComponentPath}>.

El parser mantiene defaults seguros: no resuelve DTDs ni entidades generales externas, acepta whitespace/misc valido fuera del root y conserva comentarios o CDATA solo cuando la configuracion lo solicita.

query y transform son subsets deliberados para el motor generico. No implementan XQuery, XSLT ni ejecucion de codigo externo. schema valida contratos propios y deja XSD completo como extension futura.

signature no debe usarse para cumplimiento criptografico legal todavia. XMLDSig puede firmar SignedInfo con RSA-SHA256 real usando llaves PEM/DER o PKCS#12/PFX entregados explicitamente en memoria o por rutas explicitas. Pkcs12SigningCredentials encapsula carga PFX, issuer/serial, cadena adicional y material inicial para validation data sin leer secretos implicitamente. XAdES puede emitir/verificar issuer, serial, cadena de certificados y signed properties tipadas como datos genericos entregados por configuracion/provider. XadesSigner permite orquestar firma, timestamp, validation data, archive timestamp y perfiles de validacion sin repetir la receta en cada aplicacion. SignatureValidationProfile permite declarar requisitos estrictos de referencias, algoritmos, perfil XAdES, ubicacion y material externo sin hardcodear dominios. Aun no incluye TSA RFC 3161 productiva ni validacion de confianza legal. Las politicas EPES/Baseline-B y roles son explicitos y configurables, sin politicas de dominio incrustadas.

Para llegar a perfiles productivos estrictos desde una capa externa, aun faltan capacidades genericas como TSA RFC 3161 real, validacion de confianza/cadena y revocacion con fuentes confiables. Validation data, validation profiles y archive timestamps no validan confianza legal ni consultan redes por defecto. Exclusive C14N sigue como extension futura. Estas capacidades no convierten al motor en un dominio de facturacion ni hardcodean politicas externas.

Fuera de alcance

[] Dominios de negocio. [] UBL. [] DIAN. [] SOAP como modulo de dominio. [] Facturacion electronica. [] XQuery completo. [] XSD completo. [] XAdES completo. [] Workspace multi-crate para el motor, salvo las excepciones auxiliares xdoc-macros y xdoc-cli.

Licencia y lockfile

El proyecto se distribuye bajo licencia dual MIT OR Apache-2.0, con textos completos en LICENSE-MIT y LICENSE-APACHE. Esta declaracion coincide con la metadata de xdoc-rs, xdoc-macros y xdoc-cli.

El Cargo.lock raiz se versiona porque el repositorio contiene tambien crates auxiliares y el CI debe validar un grafo reproducible. Los lockfiles anidados generados al ejecutar fixtures temporales permanecen ignorados.

Nombre de publicacion

El package runtime se publica como xdoc-rs, pero el target [lib] conserva el nombre xdoc. La ergonomia esperada en Rust sigue siendo:

use xdoc::macros::xml;

En Cargo.toml, un consumidor puede declarar la dependencia de forma explicita asi:

xdoc = { package = "xdoc-rs", version = "0.1" }

La proc-macro resuelve el nombre real del package del consumidor, por lo que tambien funciona si el usuario decide renombrar la dependencia.

Para publicar en crates.io, xdoc-macros debe publicarse primero con la misma version compatible; luego xdoc-rs puede depender de xdoc-macros = "0.1.0". En el repositorio se conserva path junto con version para desarrollo local.

El CLI se publica como package separado xdoc-cli, con binario xdoc, y depende de xdoc-rs por version compatible. Por orden de publicacion, primero va xdoc-macros, luego xdoc-rs, y finalmente xdoc-cli. En desarrollo local se ejecuta asi:

cargo run -p xdoc-cli -- validate-wellformed tests/fixtures/xml/simple.xml
cargo run -p xdoc-cli -- validate tests/fixtures/xml/simple.xml tests/fixtures/contracts/simple-list.toml

Documentos operativos

[] Context [] Instructions [] Worklogs [] Task Index

Documentacion de libreria

[] Guia general [] Documentacion por feature [] Documentacion por archivo [] Documentacion de firma

Convencion de tareas

Cada tarea debe poder ejecutarse y verificarse. El formato obligatorio es:

[] Context [] Instructions [] Checklist [] Verification [] Worklog