跳到主要内容

JSON 转 Rust 结构体 — serde derive、snake_case、Option、零上传

JSON 转 Rust struct, 粘 JSON 出带 serde derive 的结构体, 字段 snake_case, 自动 serde rename, 可空用 Option, 数组用 Vec, 嵌套对象生成子 struct。

  • 本地处理
  • 分类 开发运维
  • 适合 格式化、校验、压缩或检查和代码相关的文本。
示例:
类型、serde rename 和 Option 是怎么推断的

每个 JSON 对象生成一个命名 struct, 带 #[derive(Serialize, Deserialize)], 字段用 snake_case。当 Rust 字段名跟原始 key (camelCase、kebab-case、PascalCase) 不一致时, #[serde(rename = "wireKey")] 属性会保留原始 key, 让 (反)序列化往返。整数推断成 i64; 带小数的推断成 f64; 一个数字有时是整数有时带小数, 字段会放宽到 f64。对象数组会折叠成一个 struct —— 某些元素缺的 key (或值为 null) 会变成 Option<T>, 这是 Rust 处理可空的惯用写法。只出现过 null 的值推断成 Option<serde_json::Value>。空对象变成 HashMap<String, serde_json::Value>。打开 #[serde(default)] 后, 缺失的 key 会反序列化成 Default 而不是报错; 还能切换 pub 字段和 Debug/Clone derive 以匹配你 crate 的风格。

这个工具能做什么

把任意 JSON (GitHub API 响应、Stripe webhook、Cargo 配置、内部事件) 粘进来, 拿到一组带 `#[derive(Serialize, Deserialize)]` 的 Rust `struct` 声明, 可以直接拖进基于 serde 的 crate。原始 key 会转成符合 习惯的 snake_case 字段名, 一旦清洗后的名字跟原 key (camelCase、 kebab-case、PascalCase) 不一致, 就自动加上 `#[serde(rename = "wireKey")]`, 这样 `serde_json::from_str` 和 `to_string` 往返时线上格式不变。数字不会被一锅端: 整数样本推断成 `i64`, 带小数的推断成 `f64`, 一个字段有时是整数有时带小数时放宽到 `f64`, 避免反序列化时因为一个小数点炸掉。对象数组会折叠成一个 struct, 所以 `[{"a":1},{"a":1,"b":2}]` 出来是一个同时带两个字段的 类型, 元素是 `Vec<RootItem>`, 而不是两个几乎重复的 struct。值为 `null` 或在部分数组元素里缺失的 key 会变成 `Option<T>`, 这是 Rust 处理可空的惯用写法; 空对象变成 `HashMap<String, serde_json::Value>`。`type`、`match` 这类保留字 会自动转义成原始标识符 (`r#type`)。`pub` 字段、给每个字段加 `#[serde(default)]`、Debug/Clone derive 都能切换以匹配你 crate 的 风格; 根 struct 名可改, 输出可一键复制或下载 `.rs` 文件。全部在 浏览器里跑: JSON 不碰服务器。

工具细节

输入
文本 + 数值 + 结构化内容
页面会根据工具类型展示文本框、数值控件、文件选择或结构化输入。
输出
即时结果 + 复制 + 下载
结果区优先给出可操作结果,支持项会显示复制、下载或可视化预览。
隐私
浏览器本地处理
主工具逻辑未发现外部 API 调用,输入通常留在当前标签页内处理。
保存 / 分享
可分享链接状态
关键设置会进入 URL,复制链接后别人能复现同一组参数。
性能预算
首屏 JS ≤ 25 KB
没有声明 WASM 依赖,适合快速打开和移动端使用。
适用场景
开发运维 · 程序员
分类和职业标签用于推荐相关工具、组织内链,并帮助用户快速判断是否适合当前任务。

怎么用

  1. 1. 输入

    把内容粘贴或拖入工具面板。

  2. 2. 处理

    点击按钮,在浏览器内本地处理,文件不上传。

  3. 3. 复制 / 下载

    一键复制结果或下载到本地。

JSON 转 Rust 结构体 适合怎么用

适合穿插在写代码、查问题、做 Review、上线前的小任务里。

适合开发场景

  • 格式化、校验、压缩或检查和代码相关的文本。
  • 把片段整理好再放进文档、工单、提交或交接材料。
  • 不切换工具,快速检查一个小 payload。

开发检查项

  • 压缩、混淆这类不可逆处理,先对副本操作。
  • 除非确认工具本地处理,不要粘贴密钥和敏感片段。
  • 转换后的代码上线前,仍要跑自己的测试或 lint。

下一步可以接着做

这些入口会把当前任务接到更完整的工具链里。

  1. 1 JSON 转 Go 结构体 JSON 转 Go struct, 粘 JSON 出带 json tag 的结构体, 字段自动导出, 嵌套对象生成子 struct, 可空字段用指针, 支持 int64 与 omitempty。 打开
  2. 2 JSON 转 TypeScript Interface JSON 转 TypeScript interface, 粘 JSON 出干净 interface, 数组元素合并为 union, 可选字段自动识别, 根类型名可命名。 打开
  3. 3 JSON 转 Java 类 JSON 转 Java POJO、record 或 Lombok @Data, 粘 JSON 出 camelCase 字段, 带 getter/setter, Jackson @JsonProperty 或 Gson @SerializedName, 嵌套类, 基本类型与装箱推断。 打开

真实使用场景

  • 接第三方 API 时不再手写结构体

    你在用 Rust 接 GitHub API, user 对象有 30 多个字段。curl 一次 拿到响应, 粘进来, 根名设为 `GitHubUser`, 复制输出到 `src/github.rs`。嵌套的 `plan` 对象自动抽成 `GitHubUserPlan`, `html_url` 保持 snake_case, `serde_json::from_str` 填进一个 完全类型化的 struct, 而不是一个要用脆弱的 `["plan"]["seats"]` 链去索引的 `serde_json::Value`。

  • 把 camelCase 的 API 映射到符合习惯的 Rust 字段

    一个 JS 前端的后端发来 `{ "userId": 7, "isActive": true, "createdAt": "..." }`。粘进来, 字段变成 `user_id`、 `is_active`、`created_at`, 每个都带 `#[serde(rename = "userId")]`。 你拿到读起来自然的 snake_case Rust, serde 层在线上仍说 API 的 camelCase, 既不用手写 rename 注解, 也没有 clippy 的 `non_snake_case` 警告。

  • 给不稳定的 webhook payload 决定 Option 还是必需

    某第三方的 webhook 有时带 `cancelled_at`, 有时不带。把前几次 payload 记下来, 作为 JSON 数组粘进来, 可选字段识别会把 `cancelled_at` 包成 `Option<String>`。现在 `match event.cancelled_at { Some(ts) => ..., None => ... }` 就能干净地区分"已取消"和"仍有效", 而不是在反序列化时因为 缺 key 而 panic。

  • 把 serde_json::Value 大杂烩替换成真正的类型

    老代码是 `let data: serde_json::Value = serde_json::from_str(s)?`, 然后到处用 `data["user"]["id"].as_i64()` 加 `.unwrap()`。抓一个 有代表性的响应粘进来, 生成结构体, 直接反序列化进去。那些在 生产 panic 的 `.as_i64().unwrap()` 链消失了, `i64` 和 `f64` 在字段层面就推断好了, 编译器检查每一次访问。

  • 给 Rust 服务生成配置类型

    你的服务读一个 `config.json`。粘进来, 根名 `Config`, 打开 `#[serde(default)]` 让残缺的配置文件也能反序列化, 拿到 `Config`、`ConfigServer`、`ConfigServerTls` 嵌套结构体, 端口是 `i64`, 开关是 `bool`。放进 `config.rs`, 调 `serde_json::from_reader(file)?`, 配置在编译期就被类型检查, 而不是运行时因为一个拼错的 key 才挂。

常见踩坑

  • 粘一个对象进来然后期待某些字段是 Option。单个对象没有"key 缺失"信号, 所以所有字段都是必需。Option 推断只在"多个对象组成的数组"里 (有的元素带某个 key、有的不带), 或者值为 null 时才生效。想从一个样本探索可选性, 把它包成 `[{...}]`。

  • 期待 ID 用 u64 / i32。JSON 不给符号也不给宽度, 所以所有整数都推断成 i64, 是安全的超集。负值会让 u64 崩, i32 在毫秒时间戳或雪花 ID 上会溢出。只在你知道真实取值域时手动收窄类型; 默认值永远能编译、永远能反序列化。

  • 把一个只出现过 null 的字段当成有类型的字段。`{"meta": null}` 出来是 `Option<serde_json::Value>`, 因为 null 不带类型信息。如果你知道真实形状, 喂一个非 null 样本 (`{"meta": {"k": 1}}`), 工具才能推出像样的 struct。

  • 忘了开 serde 的 derive feature。输出用了 `#[derive(Serialize, Deserialize)]`, 需要 Cargo.toml 里写 `serde = { version = "1", features = ["derive"] }`。不开 `derive` feature 代码编译不过; 而且只要输出里有 `serde_json::Value` 或 `HashMap` 兜底, 就还需要 `serde_json`。

  • 粘 JSON5 / 带注释的 JSON / 末尾逗号。我们用严格的 `JSON.parse`, 注释、不带引号的 key、末尾逗号都会报错。先剥掉, 或者先过一道 JSON 格式化工具。

隐私说明

你粘进来的 JSON 不会离开这个浏览器标签页。解析和类型推断走浏览器 内建的 `JSON.parse`, 没有任何网络请求, 也不对文本框内容做 analytics。 分享链接会把你的输入和选项编码进 URL 以便复现结果, 也就是说由你 决定何时分享。如果 payload 敏感 (内部 ID、客户数据、生产响应), 直接复制生成的 Rust 代码, 不要分享链接。只有选项布尔值 (pub / serde default / Debug+Clone) 会存进 localStorage, 让你偏好的风格 在多次访问之间保留。

常见问题

类似工具组合

做你这行的人, 还会一起用这些。

Made by Toolora · 100% client-side · Updated 2026-06-14