Conversor de Rust a XML
Pega structs de Rust o un struct literal. Recibe XML limpio al instante.
Qué hace esta herramienta
Si alguna vez te ha tocado escribir a mano XML que refleje un struct de Rust — para un cliente SOAP en un servicio de integración, un fichero de configuración o una fixture de test — sabes la cantidad de copiar y pegar que eso supone. Pega el Rust aquí y recibes XML bien formado de una sola pasada. Un único struct, un fichero con varios structs y enums, o un let order = Order { ... }; ya poblado — mismo resultado: un documento XML completo con cada campo preservado.
No es sustitución boba de strings. El conversor sabe cómo serializa Rust realmente a través de serde — más o menos como lo emitirían serde-xml-rs o quick-xml. f64 y f32 salen como texto numérico plano, los valores String van escapados para XML, un Option<T> con None se convierte en elemento vacío (o se omite cuando hay #[serde(skip_serializing_if = "Option::is_none")]), y Vec<T> sigue una forma de contenedor consistente — cada Vec pasa a ser un elemento envoltorio con un hijo por ítem, nombrado según el tipo del elemento.
Los atributos de serde se respetan. #[serde(rename = "x")] sobre un campo renombra el elemento en la salida, #[serde(rename = "x")] sobre el struct renombra el root envolvente, #[serde(skip)] elimina el campo y #[serde(flatten)] sube un struct anidado un nivel. Los enums se emiten con las reglas de tagging estándar de serde — externally-tagged por defecto, adjacently o internally tagged si pones #[serde(tag = "...")]. Si quieres la versión a fondo, The Rust Book es un buen punto de partida para entender ownership y el sistema de tipos que hay por debajo.
Cómo usarla
Tres pasos. Funciona igual tanto si pegas un struct de cinco líneas como un módulo entero.
Pega tu Rust (o prueba el ejemplo)
Coloca tu Rust en el editor de la izquierda tal cual. Un struct, un enum, un struct literal ya poblado, o un fichero con varios tipos — todo vale. Pulsa Cargar ejemplo si quieres ver primero un caso realista.
No hace falta quitar las sentencias use, los derive ni las anotaciones de lifetime. Deja el código tal y como lo dejó rustfmt. Solo pega.
Pulsa Convertir
Haz clic en el botón verde Convertir. La herramienta lee el Rust, preserva cada struct y campo, y construye el XML de una pasada. Verás un pequeño indicador de carga mientras corre.
Copia el XML
El panel de la derecha se llena con XML indentado y bien formado que cualquier parser XML estándar aceptará. Cópialo directo a tu petición SOAP, al fichero de config o a la fixture del test.
Cuándo viene realmente bien
Integración SOAP a nivel de sistema
Los servicios Rust a menudo conviven con sistemas legacy que siguen hablando SOAP. Pega tu struct de petición, coge el cuerpo XML, pruébalo en SoapUI antes de cablear el cliente HTTP — más rápido que escribir el envelope a mano. Combínalo con un crate de <a href="https://crates.io/" target="_blank" rel="noopener">crates.io</a> como <code>reqwest</code> para el transporte.
Ficheros de configuración para servicios y demonios
Un struct de settings con más de 30 campos se convierte en una plantilla XML lista para editar. Sin boilerplate escrito a mano, sin olvidar campos cuando el struct crezca.
Seed de fixtures para tests
Convierte un <code>let order = Order { ... };</code> poblado de un test unitario en un fichero XML de seed para tests de integración, mock servers o sistemas legacy que no controlas.
Mantener la documentación al día
Genera ejemplos XML para un README, los docs del crate o la documentación de un schema respaldada por XSD directamente desde tus structs reales, para que la documentación coincida con el código en vez de ir a la deriva.
Preguntas frecuentes
¿Puedo pegar varios structs de golpe?
Sí — pega un módulo entero. Cada struct o enum de nivel superior sale con los tipos anidados expandidos y los valores por defecto rellenados. Nada se descarta en silencio.
¿Respeta #[serde(rename)] y #[serde(skip)]?
Sí. #[serde(rename = "x")] sobre un campo renombra el elemento XML, #[serde(rename = "x")] sobre el struct renombra el root envolvente, #[serde(skip)] elimina el campo entero y #[serde(flatten)] sube un struct anidado un nivel. #[serde(rename_all = "PascalCase")] se aplica a todos los campos del struct. Eso coincide con lo que serde hace realmente en runtime.
¿Cómo trata Option<T> y skip_serializing_if?
Un None pasa a elemento vacío por defecto — así la forma se mantiene consistente y los XSD siguen validando. Si el campo lleva #[serde(skip_serializing_if = "Option::is_none")], los None se descartan del todo. Some(x) siempre se serializa como x.
¿Y los enums, Vec y HashMap?
Los enums van por defecto como externally-tagged (<VariantName>...</VariantName>); añade #[serde(tag = "type")] para pasar a internally-tagged. Vec<T> pasa a un elemento contenedor con un hijo por ítem, nombrado según el tipo — un Vec<OrderItem> items se convierte en <items><OrderItem/><OrderItem/></items>. HashMap<K,V> pasa a un contenedor de <Entry><Key/><Value/></Entry>.
¿Se guarda mi código?
Tu código se envía al backend para la conversión y no se persiste — no registramos el payload. Como siempre con las herramientas online, si el código es realmente sensible, revísalo antes de pegarlo.
¿Qué pasa si el Rust usa lifetimes, traits o bloques unsafe?
Las anotaciones de lifetime se ignoran a efectos de XML — no afectan al valor en runtime. Las definiciones de trait describen forma, no contenido, así que no producen XML directamente; los structs que las implementan sí. Los bloques unsafe se ignoran porque son construcciones de ejecución. Si el código tiene errores de sintaxis, arregla primero los obvios — el parser es tolerante pero no adivino.
Otras herramientas que te pueden venir bien
Rust a XML es una pieza del puzle. Estas encajan bien: