JSON.mapping 如果 "root" 属性具有继承键

JSON.mapping if "root" attribute has inherit keys

我收到下一个表单的回复:

resp = "{
  \"response\":
    {\"some\":
      {\"next\":
        {\"user\":
          {\"name\":\"Oleg\"}
        }
      }
    }
}"

我使用 JSON.mapping 合并来自 JSON

的用户
struct User
  JSON.mapping(
    f_name: {type: String, key: "name", root: "WHAT.ABOUT.ROOT"}
  )
end

在这种情况下,当我有继承键时,如何使用 root 属性?

user = User.from_json(resp)

我试过了root: "response.some.next.user"但是没用

谢谢!

您似乎只能使用 root 跳过一层对象嵌套。 "response.some.next.user" 是一个有效的 JSON 键,因此它可以在

这样的文档中用作 root
{ "response.some.next.user": { "name": "Oleg" } }

尽管这不是您要的。

在 Crystal 标准库规范中有一些使用 root 的示例,spec/std/json/mapping_spec.cr

我找到了解决方案:

require "json"
private struct Response
  JSON.mapping(
    result: {type: Result, key: "get_users_response"}
  )  
end

private struct Result
  JSON.mapping(
    client: {type: Client, key: "get_users_result"}
  )
end

struct Client
  JSON.mapping(
    user: {type: User, key: "user"}
  )  
end

struct User
  JSON.mapping(
    id: {type: String, key: "id"},
    f_name: {type: String, key: "first_name"},
    l_name: {type: String, key: "last_name"}
  )
end

resp  = "{\"get_users_response\":{\"get_users_result\":{\"status\":\"Success\",\"error_code\":\"200\",\"user\":{\"id\":\"10\",\"first_name\":\"Oleg\",\"last_name\":\"Sobchuk\"}}}}"

response_container = Response.from_json(resp)
puts response_container
puts response_container.result.client.user

看起来有点难,但是很管用https://play.crystal-lang.org/#/r/1k3a

编辑

根据 THIS BENCHMARK 架构 JSON 解析速度稍快,使用的内存也少得多。