Its not entirely clear from the documentation how to use Jason.Encode.
I have the following structure:
%GoogleApi.Storage.V1.Model.Bucket{
acl: nil,
billing: nil,
cors: nil,
defaultEventBasedHold: false,
defaultObjectAcl: nil,
encryption: nil,
etag: "CAE=",
iamConfiguration: %GoogleApi.Storage.V1.Model.BucketIamConfiguration{
bucketPolicyOnly: %GoogleApi.Storage.V1.Model.BucketIamConfigurationBucketPolicyOnly{
enabled: false,
lockedTime: nil
},
uniformBucketLevelAccess: %GoogleApi.Storage.V1.Model.BucketIamConfigurationUniformBucketLevelAccess{
enabled: false,
lockedTime: nil
}
},
id: "fafdafdaf",
kind: "storage#bucket",
labels: nil,
lifecycle: nil,
location: "US",
locationType: "multi-region",
logging: nil,
metageneration: "1",
name: "fafdafdaf",
owner: nil,
projectNumber: "454545",
retentionPolicy: nil,
selfLink: "https://www.googleapis.com/storage/v1/b/fafdafdaf",
storageClass: "STANDARD",
timeCreated: ~U[2020-03-05 02:00:31.923Z],
updated: ~U[2020-03-05 02:00:31.923Z],
versioning: nil,
website: nil
},
%GoogleApi.Storage.V1.Model.Bucket{
acl: nil,
billing: nil,
cors: nil,
defaultEventBasedHold: false,
defaultObjectAcl: nil,
encryption: nil,
etag: "CAE=",
iamConfiguration: %GoogleApi.Storage.V1.Model.BucketIamConfiguration{
bucketPolicyOnly: %GoogleApi.Storage.V1.Model.BucketIamConfigurationBucketPolicyOnly{
enabled: false,
lockedTime: nil
},
uniformBucketLevelAccess: %GoogleApi.Storage.V1.Model.BucketIamConfigurationUniformBucketLevelAccess{
enabled: false,
lockedTime: nil
}
},
id: "gcs_bucket_api",
kind: "storage#bucket",
labels: nil,
lifecycle: nil,
location: "US",
locationType: "multi-region",
logging: nil,
metageneration: "1",
name: "gcs_bucket_api",
owner: nil,
projectNumber: "454545",
retentionPolicy: nil,
selfLink: "https://www.googleapis.com/storage/v1/b/gcs_bucket_api",
storageClass: "STANDARD",
timeCreated: ~U[2020-03-05 01:34:16.147Z],
updated: ~U[2020-03-05 01:34:16.147Z],
versioning: nil,
website: nil
}
]
I would like to give the whole thing as JSON but it says I need to implement it using @derive Jason.Encode. But I don’t understand how that would be done given the example from documentation adding the following did not help:
"Jason.Encoder protocol must always be explicitly implemented.\n\nIf you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:\n\n @derive {Jason.Encoder, only: [....]}\n defstruct ...\n\nIt is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:\n\n @derive Jason.Encoder\n defstruct ...\n\nFinally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:\n\n Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])\n
Given the following:
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
conc = GoogleApi.Storage.V1.Connection.new(token.token)
{:ok, response} = GoogleApi.Storage.V1.Api.Buckets.storage_buckets_list(conc, "PROJECT")
What is the right way to make response.items which is a list of structs with nested structs into JSON using Jason?
Solution I came up without Jason works great, but would be cleaner if I used Jason to encode my structs?
data = Enum.map(response.items, fn x ->
x = Map.update!(x, :iamConfiguration, &(Map.from_struct(&1)) )
x_iamConf = Map.get(x, :iamConfiguration)
x = Map.update!(x, :iamConfiguration, fn x_iamConf ->
x_iamConf = Map.update!(x_iamConf, :bucketPolicyOnly, &(Map.from_struct(&1)))
x_iamConf = Map.update!(x_iamConf, :uniformBucketLevelAccess, &(Map.from_struct(&1)))
end)
x = Map.from_struct(x)
end)
json(conn, data)