init(from:)で独自のデコード処理を記述することが出来ます。以下のコードでフラットなJSONからネストしたオブジェクトにデコードすることが出来ます。
struct User: Codable {
    struct Address: Codable {
        let street: String
        let city: String
        let state: String
    }
    let name: String
    let address: Address
    
    private enum CodingKeys: String, CodingKey {
        case name
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        address = try Address(from: decoder)
    }
}
let data = """
{
"name": "rizumita",
"street": "1-2-3 Foo",
"city": "Bar",
"state": "Baz"
}
""".data(using: .utf8)!
let decoder: JSONDecoder = JSONDecoder()
do {
    let user: User = try decoder.decode(User.self, from: data)
    print(user)
} catch {
    print(error)
}