# Create struct from YAML

**URL:** https://discourse.julialang.org/t/create-struct-from-yaml/86429
**Category:** General Usage
**Tags:** question
**Created:** [August 27, 2022, 12:50pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429 "2022-08-27T12:50:49Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [August 27, 2022, 12:50pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/1 "2022-08-27T12:50:49Z")

</div>

I have the following code:

```julia
using YAML, StructTypes, Parameters

 @with_kw struct Test
    can_log::String
    sys_log::String
    version::String
    info::String
end

data = YAML.load_file("data/config.yaml")
test = data["tests"][1]
println(test)

```

and data (config.yaml):

```julia
tests:
    - can_log: data/27-08-2022/logfile.csv
      sys_log: data/27-08-2022/syslog
      version: 1.7.1
      info: first test
    - can_log: data/28-08-2022/logfile.csv
      sys_log: data/28-08-2022/syslog
      version: 1.7.2
      info: second test

```

If I run the script the output is:

```julia
julia> test
Dict{Any, Any} with 4 entries:
  "sys_log" => "data/27-08-2022/syslog.csv"
  "can_log" => "data/27-08-2022/logfile.csv"
  "version" => "1.7.1"
  "info" => "first test"

```

How can I convert this dict into a struct of the type **Test**?

---

<div class="post-metadata">

### Author: ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)
#### Post date: [August 27, 2022, 1:27pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/2 "2022-08-27T13:27:41Z")

</div>

The StructTypes.jl package has a `StructTypes.constructfrom` function that will do this for you (assuming you have a StructType defined for your type).

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [August 27, 2022, 3:15pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/3 "2022-08-27T15:15:02Z")

</div>

It is not clear for me - after reading the documentation - how to do that.

Not working:

```julia
using YAML, StructTypes

mutable struct Test
    can_log::String
    sys_log::String
    version::String
    info::String
    Test() = new()
end

data = YAML.load_file("data/config.yaml")
test = data["tests"][1]
println(test)

StructTypes.StructType(::Type{Test}) = StructTypes.Mutable()
StructTypes.constructfrom(Test, test)

```

Error message:

```julia
julia> include("src/read.jl")
Dict{Any, Any}("sys_log" => "data/27-08-2022/syslog", "can_log" => "data/27-08-2022/logfile.csv", "version" => "1.7.1", "info" => "first test")
ERROR: LoadError: MethodError: no method matching applyfield!(::StructTypes.Closure{String}, ::Test, ::String)
Closest candidates are:
  applyfield!(::Any, ::T, ::Symbol) where T at ~/.julia/packages/StructTypes/Cw0JM/src/StructTypes.jl:780
Stacktrace:
 [1] constructfrom!(#unused#::StructTypes.Mutable, x::Test, #unused#::StructTypes.DictType, obj::Dict{Any, Any})
   @ StructTypes ~/.julia/packages/StructTypes/Cw0JM/src/StructTypes.jl:1025
 [2] constructfrom!
   @ ~/.julia/packages/StructTypes/Cw0JM/src/StructTypes.jl:1016 [inlined]
 [3] constructfrom
   @ ~/.julia/packages/StructTypes/Cw0JM/src/StructTypes.jl:1006 [inlined]
 [4] constructfrom(#unused#::Type{Test}, obj::Dict{Any, Any})
   @ StructTypes ~/.julia/packages/StructTypes/Cw0JM/src/StructTypes.jl:919
 [5] top-level scope
   @ ~/repos/config/src/read.jl:16
 [6] include(fname::String)
   @ Base.MainInclude ./client.jl:476
 [7] top-level scope
   @ REPL[1]:1
in expression starting at /home/ufechner/repos/config/src/read.jl:16

```

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [August 27, 2022, 3:50pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/4 "2022-08-27T15:50:18Z")

</div>

1. `StructTypes.Mutable()` requires an empty constructor in the type, `Test() = new()`. `StructTypes.Struct()` doesn’t require it, and is also an option here, if the YAML files can be relied upon to always provide these four fields.

> Though slightly less performant than `StructTypes.Struct`, `Mutable` is a much more robust method for mapping Julia struct fields for serialization. …  
> This flow has the nice properties of: allowing object construction success even if fields are missing in the input, and if “extra” fields exist in the input that aren’t apart of the Julia struct’s fields, they will automatically be ignored. This allows for maximum robustness when mapping Julia types to arbitrary data foramts that may be generated via web services, databases, other language libraries, etc.

(in short, `StructTypes.Struct` is slightly more performant, but `StructTypes.Mutable` is more robust to data issues in the input YAML file.)

1. It seems the keys have to be `Symbol`s for the construction to work. Either convert them after reading:

```julia
test = Dict(Symbol(k) => v for (k, v) in data["tests"][1])

```

or read them in as `Symbol`s in the first place:

```julia
julia> data = YAML.load_file("filename.yml"; dicttype=Dict{Symbol,Any})

```

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [August 27, 2022, 3:55pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/5 "2022-08-27T15:55:20Z")

</div>

Thanks a lot!

This works:

```julia
using YAML, StructTypes

 mutable struct Test
    can_log::String
    sys_log::String
    version::String
    info::String
    Test() = new()
end

data = YAML.load_file("data/config.yaml"; dicttype=Dict{Symbol,Any})
test_dict = data[:tests][1]
println(test_dict)

StructTypes.StructType(::Type{Test}) = StructTypes.Mutable()
test = StructTypes.constructfrom(Test, test_dict)

```

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [August 27, 2022, 4:08pm UTC](https://discourse.julialang.org/t/create-struct-from-yaml/86429/6 "2022-08-27T16:08:38Z")

</div>

Or the complete code that converts an array of dicts from YAML to an array of structs in Julia:

```julia
using YAML, StructTypes

 mutable struct Test
    can_log::String
    sys_log::String
    version::String
    info::String
    Test() = new()
end
StructTypes.StructType(::Type{Test}) = StructTypes.Mutable()

const tests = Test[]

data = YAML.load_file("data/config.yaml"; dicttype=Dict{Symbol,Any})

for test_dict in data[:tests]
    test = StructTypes.constructfrom(Test, test_dict)
    push!(tests, test)
end

tests

```
