Rust에서 XML로 변환기
Rust 구조체나 구조체 리터럴을 붙여넣으세요. 깔끔한 XML로 돌려드립니다.
이 도구가 하는 일
통합 서비스의 SOAP 클라이언트, 시스템 설정 파일, 테스트 픽스처 등을 위해 Rust 구조체를 반영하는 XML을 손으로 만들어 본 적이 있다면, 그게 얼마나 많은 복붙을 요구하는지 잘 아실 겁니다. 여기에 Rust를 붙여넣으면 한 번에 잘 형식화된 XML을 돌려받습니다. 구조체 하나, 여러 구조체와 enum이 들어있는 파일, 값이 채워진 let order = Order { ... }; 리터럴 — 결과는 모두 같습니다: 모든 필드가 보존된 완전한 XML 문서.
멍청한 문자열 치환이 아닙니다. 이 변환기는 Rust가 serde를 통해 실제로 어떻게 직렬화하는지를 압니다 — serde-xml-rs나 quick-xml이 출력하는 것과 거의 같은 방식입니다. f64와 f32는 단순 숫자 텍스트로, String 값은 XML 이스케이프 처리되어 나오고, None을 담은 Option<T>는 빈 요소가 됩니다(#[serde(skip_serializing_if = "Option::is_none")]가 설정되어 있으면 생략). Vec<T>는 일관된 컨테이너 형태를 따르며 — 각 Vec은 요소 타입 이름이 붙은 자식 하나짜리 래퍼 요소가 됩니다.
serde 속성은 모두 존중됩니다. 필드의 #[serde(rename = "x")]는 출력의 요소명을 바꾸고, 구조체의 #[serde(rename = "x")]는 감싸는 root를 바꾸며, #[serde(skip)]는 필드를 버리고, #[serde(flatten)]은 중첩 구조체를 한 단계 위로 끌어올립니다. enum은 serde 표준 태깅 규칙으로 출력됩니다 — 기본은 externally tagged, #[serde(tag = "...")]를 설정하면 adjacently 또는 internally tagged로 바뀝니다. 더 깊이 알고 싶다면 The Rust Book이 그 밑의 소유권과 타입 시스템을 이해하는 좋은 출발점입니다.
사용 방법
세 단계. 다섯 줄짜리 구조체든 모듈 전체든 동작은 동일합니다.
Rust 붙여넣기 (또는 샘플 사용)
왼쪽 에디터에 Rust를 있는 그대로 넣어주세요. 구조체, enum, 값이 채워진 구조체 리터럴, 또는 여러 타입이 있는 파일 — 전부 괜찮습니다. 현실적인 예제를 먼저 보고 싶다면 샘플 불러오기를 클릭하세요.
use 문을 걷어내거나 derive 매크로를 제거하거나 라이프타임 어노테이션을 정리할 필요 없습니다. rustfmt가 남긴 그대로 두세요. 그냥 붙여넣기만 하면 됩니다.
변환 누르기
초록색 변환 버튼을 클릭하세요. 도구가 Rust를 읽고 모든 구조체와 필드를 보존해 한 번에 XML을 만듭니다. 실행 중에는 짧은 로딩 표시가 나타납니다.
XML 복사
오른쪽 패널이 표준 준수 XML 파서가 받아들이는, 들여쓰기가 된 잘 형식화된 XML로 채워집니다. SOAP 요청, 설정 파일, 테스트 픽스처에 그대로 붙여넣으세요.
실제로 유용한 순간
시스템 레벨 SOAP 연동
Rust 서비스는 종종 여전히 SOAP를 쓰는 레거시 시스템 옆에 배치됩니다. 요청 구조체를 붙여넣고 XML 바디를 뽑아 HTTP 클라이언트를 연결하기 전에 SoapUI에서 테스트 — envelope를 손으로 쓰는 것보다 빠릅니다. 트랜스포트에는 <a href="https://crates.io/" target="_blank" rel="noopener">crates.io</a>의 <code>reqwest</code> 같은 크레이트를 함께 쓰세요.
서비스와 데몬의 설정 파일
30개가 넘는 필드를 가진 설정 구조체가 편집하기 좋은 XML 템플릿이 됩니다. 손으로 쓴 보일러플레이트 없고, 구조체가 커져도 빠뜨리는 필드 없습니다.
테스트 픽스처 시드
단위 테스트에서 값이 채워진 <code>let order = Order { ... };</code>를 통합 테스트, 목 서버 또는 내가 소유하지 않은 레거시 시스템용 XML 시드 파일로 바꾸세요.
문서를 계속 일치시키기
README, 크레이트 문서, XSD 기반 스키마 문서용 XML 예제를 실제 구조체에서 바로 생성해, 문서가 코드와 멀어지지 않고 일치하도록 유지합니다.
자주 묻는 질문
여러 구조체를 한 번에 붙여넣어도 되나요?
네 — 모듈 전체를 붙여넣으세요. 최상위 구조체나 enum은 각각 중첩 타입이 전개되고 기본값이 채워진 채로 나옵니다. 아무것도 조용히 사라지지 않습니다.
#[serde(rename)]과 #[serde(skip)]을 존중하나요?
네. 필드의 #[serde(rename = "x")]는 XML 요소명을 바꾸고, 구조체의 #[serde(rename = "x")]는 감싸는 root를 바꾸며, #[serde(skip)]는 필드를 완전히 버리고, #[serde(flatten)]은 중첩 구조체를 한 단계 위로 끌어올립니다. #[serde(rename_all = "PascalCase")]는 구조체 내의 모든 필드에 적용됩니다. 이는 serde가 런타임에 실제로 하는 동작과 일치합니다.
Option<T>와 skip_serializing_if는 어떻게 처리되나요?
기본적으로 None 값은 빈 요소가 됩니다 — 그래야 형태가 일관되게 유지되고 XSD 검증도 계속 통과합니다. 필드에 #[serde(skip_serializing_if = "Option::is_none")]이 있으면 None 값은 완전히 제거됩니다. Some(x)는 항상 x 그 자체로 직렬화됩니다.
enum, Vec, HashMap은 어떻게 되나요?
enum은 기본적으로 externally-tagged (<VariantName>...</VariantName>)로 출력됩니다; #[serde(tag = "type")]을 추가하면 internally-tagged로 바뀝니다. Vec<T>는 요소 타입 이름이 붙은 자식을 항목마다 하나씩 가진 컨테이너 요소가 됩니다 — Vec<OrderItem> items는 <items><OrderItem/><OrderItem/></items>가 됩니다. HashMap<K,V>는 <Entry><Key/><Value/></Entry>를 담는 컨테이너가 됩니다.
제 코드가 저장되나요?
코드는 변환을 위해 백엔드로 전송되며 저장되지 않습니다 — 페이로드 로그도 남기지 않습니다. 온라인 도구 전반에 해당하는 얘기지만, 코드가 정말 민감하다면 붙여넣기 전에 한번 훑어보세요.
Rust에 라이프타임, 트레이트, unsafe 블록이 있으면요?
라이프타임 어노테이션은 XML 목적상 제거됩니다 — 런타임 값에 영향을 주지 않습니다. 트레이트 정의는 내용이 아니라 형태를 기술하므로 직접 XML을 만들지 않습니다; 이를 구현하는 구조체가 만들어냅니다. unsafe 블록은 실행 시점의 구성이라 무시됩니다. 코드에 문법 오류가 있다면 확실한 것부터 먼저 고쳐주세요 — 파서는 관대하지만 독심술사는 아닙니다.
함께 쓰면 좋은 다른 도구
Rust에서 XML은 퍼즐의 한 조각입니다. 이런 도구들이 잘 어울립니다: