@@ -426,14 +426,39 @@ function parsetype(target_type::Type{T}, value::Any) :: T where {T}
426426 end
427427end
428428
429+ """
430+ match_field_names(::Type{T}, params::AbstractDict{Symbol}) where {T}
431+
432+ Return a copy of `params` whose keys are rewritten to the field names of `T`
433+ matched case-insensitively. Used for sources like HTTP headers, whose names are
434+ case-insensitive (and which HTTP.jl canonicalizes to Title-Case), so that a
435+ struct field `name` still matches an incoming `Name` header.
436+ """
437+ function match_field_names (:: Type{T} , params:: AbstractDict{Symbol} ) where {T}
438+ lookup = Dict (lowercase (String (k)) => v for (k, v) in params)
439+ matched = empty (params)
440+ for name in fieldnames (T)
441+ value = get (lookup, lowercase (String (name)), nothing )
442+ if ! isnothing (value)
443+ matched[name] = value
444+ end
445+ end
446+ return matched
447+ end
448+
429449"""
430450 struct_builder(::Type{T}, parameters::Dict{String,String}) where {T}
431451
432452Constructs an object of type `T` using the parameters in the dictionary `parameters`.
453+ When `casesensitive` is false, parameter names are matched to the struct's field
454+ names ignoring case (used for case-insensitive sources like HTTP headers).
433455"""
434- function struct_builder (:: Type{T} , params:: AbstractDict ) :: T where {T}
456+ function struct_builder (:: Type{T} , params:: AbstractDict ; casesensitive :: Bool = true ) :: T where {T}
435457 has_kwdef = has_kwdef_constructor (T)
436- params_with_symbols = Dict (Symbol (k) => v for (k, v) in params)
458+ params_with_symbols = Dict (Symbol (k) => v for (k, v) in params)
459+ if ! casesensitive
460+ params_with_symbols = match_field_names (T, params_with_symbols)
461+ end
437462 if has_kwdef
438463 # case 1: Use slower converter to handle structs with default values
439464 return kwarg_struct_builder (T, params_with_symbols)
0 commit comments