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 xml;
En Cargo.toml, un consumidor puede declarar la dependencia de forma explicita asi:
= { = "xdoc-rs", = "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:
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