Skip to content

Commit a99a04f

Browse files
authored
Allow specifying multiple names to be matched against in field tags. Implements suggestion in #18 (#26)
1 parent 3266dd0 commit a99a04f

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/StructUtils.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ keyeq(a::Symbol, b::String) = a === Symbol(b)
599599
keyeq(a::String, b::Symbol) = Symbol(a) == b
600600
keyeq(a, b::String) = string(a) == b
601601
keyeq(a::AbstractString, b::String) = String(a) == b
602+
keyeq(a, b::Tuple) = any(keyeq(a), b)
602603
keyeq(a, b) = isequal(a, b)
603604
keyeq(x) = y -> keyeq(x, y)
604605

@@ -926,7 +927,7 @@ function findfield(::Type{T}, k, v, f) where {T}
926927
fn = f.fsyms[i]
927928
ftags = fieldtags(f.style, T, fn)
928929
field = get(ftags, :name, fn)
929-
if k == field
930+
if keyeq(k, field) || keyeq(k, fn)
930931
symval, symst = make(f.style, fieldtype(T, i), v, ftags)
931932
setval!(f.vals, symval, i)
932933
return EarlyReturn(symst)

test/runtests.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,48 @@ end
326326
@test StructUtils.make(Dict{Symbol, Int}, (;)) == Dict{Symbol, Int}()
327327
end
328328

329+
@testset "keyeq with Tuple" begin
330+
# Test basic tuple functionality
331+
@test StructUtils.keyeq(:a, ("a", "b", "c"))
332+
@test StructUtils.keyeq("a", ("a", "b", "c"))
333+
@test StructUtils.keyeq("b", ("a", "b", "c"))
334+
@test StructUtils.keyeq("c", ("a", "b", "c"))
335+
@test !StructUtils.keyeq("d", ("a", "b", "c"))
336+
@test !StructUtils.keyeq(:d, ("a", "b", "c"))
337+
338+
# Test with Symbol/String mixing
339+
@test StructUtils.keyeq(:myfield, ("MyField", "myfield", "field_my"))
340+
@test StructUtils.keyeq("MyField", ("MyField", "myfield", "field_my"))
341+
@test StructUtils.keyeq("myfield", ("MyField", "myfield", "field_my"))
342+
@test StructUtils.keyeq("field_my", ("MyField", "myfield", "field_my"))
343+
@test !StructUtils.keyeq("other", ("MyField", "myfield", "field_my"))
344+
345+
# Test with empty tuple
346+
@test !StructUtils.keyeq("a", ())
347+
348+
# Test with single element tuple
349+
@test StructUtils.keyeq("a", ("a",))
350+
@test !StructUtils.keyeq("b", ("a",))
351+
352+
# Test that existing keyeq methods still work
353+
@test StructUtils.keyeq(:a, "a")
354+
@test StructUtils.keyeq("a", :a)
355+
@test StructUtils.keyeq("a", "a")
356+
@test StructUtils.keyeq(1, 1)
357+
@test !StructUtils.keyeq(1, 2)
358+
359+
# Test practical use case: struct with alternative field names
360+
# Use name directly (not in a namespace) for DefaultStyle
361+
@tags struct SomeStruct
362+
my_field::Int & (name=("MyField", "myfield", "field_my"),)
363+
end
364+
365+
# Test that make works with different key names
366+
@test StructUtils.make(SomeStruct, Dict("MyField" => 42)).my_field == 42
367+
@test StructUtils.make(SomeStruct, Dict("myfield" => 43)).my_field == 43
368+
@test StructUtils.make(SomeStruct, Dict("field_my" => 44)).my_field == 44
369+
# Test that the original field name still works
370+
@test StructUtils.make(SomeStruct, Dict(:my_field => 45)).my_field == 45
371+
end
372+
329373
end

0 commit comments

Comments
 (0)