Golang yaml.v2 struct with a map[string]string unmarshalling fails - parsing

Im am using the gopkg.in/yaml.v2 package and I'm trying to unmarshal a yaml file like this:
Sizes:
A: small
B: small
C: medium
I created a go struct like this:
type sizesByType struct {
Map map[string]string `yaml: "Sizes"`
}
but unmarshaling it with yaml.v2 gives me an empty map.
What am I doing wrong?

Remove the space in your struct tag:
type sizesByType struct {
Map map[string]string `yaml:"Sizes"`
}

Related

How to fix this circular reference error involving Protocols and type aliases?

The below code snippet, which is taken from this Github issue, fails to compile on Xcode 14.1
enum GenericState<Mode>: Hashable where Mode: Hashable {}
// error: Circular reference
protocol P {
associatedtype Mode: Hashable
// (false positive error) - Type 'Self.Mode' does not conform to protocol 'Hashable'
typealias SomeState = GenericState<Mode>
typealias Foo = [CustomKeyPath<Self, String>]
}
struct Interface<Base> where Base: P {}
typealias CustomKeyPath<Base, T> = KeyPath<Interface<Base>, T> where Base: P
See screenshot of errors:
So, apparently, the latest swift update has some issues with Circular references.
How should I go about fixing these errors?

Returning Array from Function (Swift)

This is my first question so please, be gentle!
I've been debugging my code and searching stackexchange.com for a while, and as best as I can tell, my problem has to do with return an array from a function. I can assure you that this is not a homework question, and I've tried going through Stackoverflow for solutions, and I'm at my wits end!
The ActiveModelResponseList is used to display a list of acceptable responses to the user, arranged in a List form:
struct ActiveModelResponseList: View {
var activeModel: ActiveModel
var body: some View {
List(activeModel.validResponses()) { /* XCode error: "Cannot convert value of type
'[ValidResponse]' to expected
argument type 'Range<Int>'" */
HStack { /* XCode error: "Contextual closure type '() -> TupleView<(Text, Text, Spacer)>'
expects 0 arguments, but 1 was used in closure body" */
Text($0.response)
Text($0.narrative)
Spacer()
}.padding(10)
}
}
}
I have tried a number of different ways to restructure the above body, and it's specifically that activeModel.validResponses() that causes the errors. If I delete it and populate the list with hard coded values, it works just fine.
That function, activeModel.validResponses() comes from the ActiveModel class, as follows:
class ActiveModel {
var baseModel: ModelData
private var responses: [Int]
private var activeElement: Int
// Although forThisElement is unused in the base function, ActiveModel still has
// such an element, used for other purposes
public func validResponses() -> [ValidResponse] {
return (baseModel.validResponses(forThisElement: activeElement))
}
}
This, in turn, comes from a base class, ModelData. Note that forThisElement is not actually required for this function, but is included to maintain polymorphism (i.e. other models will use it). As you can see, ModelData.validResponses returns a [ValidResponse]
class ModelData: Hashable, Codable, Identifiable {
var id: Int
var valid_response: [String]
var valid_response_narrative: [String]
public func validResponses(forThisElement: Int) -> [ValidResponse] {
// forThisElement is currently an unused input variable,
// but is required for compatibility with other classes
var thisResult: [ValidResponse] = []
for thisResponse in 0..<valid_response.count {
thisResult[thisResponse].id = thisResponse
thisResult[thisResponse].response = valid_response[thisResponse]
thisResult[thisResponse].narrative = valid_response_narrative[thisResponse]
}
return thisResult
}
}
The ValidResponse is just an ordinary struct, defined as follows:
struct ValidResponse: Identifiable, Hashable {
var id: Int = 0
var response: String = "0"
var narrative: String = "Default"
}
The preview is being generated for an iPod touch (7th generation), I'm using Xcode Version 13.1 (13A1030d), and am compiling using MacOS 12.0.1, on a mid-2015 MacBook Pro.
I found the following answers on stackexchange, but I feel none the wiser after having read them (and, as these answers are quite dated, I wonder if they're still relevant):
returning an array from a function in Swift
Return Array from Function in Swift
Square every element in an Int of arrays. (Swift)
Can anyone provide any guidance?
The first error message is nonsense. Fix the second and it will disappear.
The title of your question is unrelated to your actual problem, which is that you're trying to use a positional parameter from an outer closure. That doesn't work; they can't propagate that way. Every new closure scope gets its own set of positional parameters, and HStack.init doesn't use any, as the error tells you.
Fix: name the argument.
List(activeModel.validResponses()) { response in
HStack {
Text(response.response)
Text(response.narrative)

Reference to generic type 'Resource' requires arguments in <…>

I have a struct as below which is confirming a protocol as below
struct ResourceItems<T: Decodable>: MyProtocol {
}
protocol MyProtocol: Decodable {
}
Now I am creating another protocol & want to access ‘ResourceItems’ in that protocol as below
protocol ObjectConverterProtocol{
var response : ResourceItems {get set}
}
But getting the error as ‘
Reference to generic type 'ResourceItems' requires arguments in <…>
’
Please guide me what I have to pass as a generic parameter. I tried with AnyObject & Any but both of them does not confirm Codable.
I can’t get how to fix this issue. Please guide.
Since ResourceItems is a generic type you need to use it like that also in your protocol. For this you can use an associated type
protocol ObjectConverterProtocol{
associatedtype ResourceType: Decodable
var response : ResourceItems<ResourceType> {get set}
}
and then you can use your protocol
struct Converter: ObjectConverterProtocol {
typealias ResourceType = String
var response: ResourceItems<ResourceType>
//or var response: ResourceItems<String>
}
or even make Converter generic
struct Converter<C: Decodable>: ObjectConverterProtocol {
typealias ResourceType = C
var response: ResourceItems<ResourceType>
}
let converter = Converter(response: ResourceItems<String>())
Since ResourceItems is a generic type, you need to specify the type of generic parameter explicitly.
Now, since the generic parameter must be Decodable, you must define the Decodable type with ResourceItems in angular brackets <...>.
Let's assume, struct DecodableObject is of a Decodable type, i.e.
struct DecodableObject: Decodable {
//....
}
So, you can now define response of type ResourceItems like so,
protocol ObjectConverterProtocol {
var response : ResourceItems<DecodableObject> {get set}
}

How to conform an enumeration to Identifiable protocol in Swift?

I'm trying to make a list with the raw values of the cases from an enumeration with the new SwiftUI framework. However, I'm having a trouble with conforming the 'Data' to Identifiable protocol and I really cannot find information how to do it. It tells me "Initializer 'init(_:rowContent:)' requires that 'Data' conform to 'Identifiable'" The stub provides me with an ObjectIdentifier variable in the last extension, but don't know what should I return. Could you tell me how do it? How do I conform Data to Identifiable, so I can make a list with the raw values?
enum Data: String {
case firstCase = "First string"
case secondCase = "Second string"
case thirdCase = "Third string"
}
extension Data: CaseIterable {
static let randomSet = [Data.firstCase, Data.secondCase]
}
extension Data: Identifiable {
var id: ObjectIdentifier {
return //what?
}
}
//-------------------------ContentView------------------------
import SwiftUI
struct Lala: View {
var name: String
var body: some View {
Text(name)
}
}
struct ContentView: View {
var body: some View {
return List(Data.allCases) { i in
Lala(name: i.rawValue)
}
}
}
⚠️ Try not to use already used names like Data for your internal module. I will use MyEnum instead in this answer
When something conforms to Identifiable, it must return something that can be identified by that. So you should return something unique to that case. For String base enum, rawValue is the best option you have:
extension MyEnum: Identifiable {
var id: RawValue { rawValue }
}
Also, enums can usually be identified by their selves:
extension MyEnum: Identifiable {
var id: Self { self }
}
⚠️ Note 1: If you return something that is unstable, like UUID() or an index, this means you get a new object each time you get the object and this will kill reusability and can cause epic memory and layout process usage beside view management issues like transition management and etc.
Take a look at this weird animation for adding a new pet:
Note 2: From Swift 5.1, single-line closures don't need the return keyword.
Note 3: Try not to use globally known names like Data for your own types. At least use namespace for that like MyCustomNameSpace.Data
Inline mode
You can make any collection iterable inline by one of it's element's keypath:
For example to self:
List(MyEnum.allCases, id:\.self)
or to any other compatible keypath:
List(MyEnum.allCases, id:\.rawValue)
✅ The checklist of the identifier: (from WWDC21)
Exercise caution with random identifiers.
Use stable identifiers.
Ensure the uniqueness, one identifier per item.
Another approach with associated values would be to do something like this, where all the associated values are identifiable.
enum DataEntryType: Identifiable {
var id: String {
switch self {
case .thing1ThatIsIdentifiable(let thing1):
return thing1.id
case .thing2ThatIsIdentifiable(let thing2):
return thing2.id
}
}
case thing1ThatIsIdentifiable(AnIdentifiableObject)
case thing2ThatIsIdentifiable(AnotherIdentifiableObject)
You can try this way:
enum MyEnum: Identifiable {
case valu1, valu2
var id: Int {
get {
hashValue
}
}
}
Copyright © 2021 Mark Moeykens. All rights reserved. | #BigMtnStudio
Combine Mastery in SwiftUI book
enum InvalidAgeError: String, Error , Identifiable {
var id: String { rawValue }
case lessThanZero = "Cannot be less than zero"
case moreThanOneHundred = "Cannot be more than 100"
}

Glossy iOS doesn't conform to protocol

I'm trying to integrate Gloss to do json parsing but I get lots of non sense errors.
I installed it with pod install and I experienced followings:
First when I import it, I got
: Cannot import underlying modules glossy, I don't know how, but after copy pasting the example from GlossExample project in github repo it disappeared.
Second if I use: struct Repo: Glossy I get error that Repo doesn't conform to protocols Decodable and Encodable but the code is pasted from the example and there exist the methods init?(json: JSON) and func toJSON() -> JSON?
Then I tried to use struct Repo: Decodable and having this function for decoder:
init?(json: JSON) {
let repoId: Int = "id" <~~ json
I get following error:
35: Binary operator '<~~' cannot be applied to operands of type 'String' and 'JSON'
Last I said OK, I won't use overloaded operators but the normal Decoder class:
init?(json: JSON) {
self.repoId = Decoder.decodeURL("id")(json)
}
I got:
Cannot convert value of type 'JSON' to expected argument type 'JSON' (aka 'Dictionary<String, AnyObject>')
Your helps and answers are welcome!
First when I import it, I got : Cannot import underlying modules glossy, I don't know how, but after copy pasting the example from GlossExample project in github repo it disappeared.
This is an issue that happens in Xcode with a few frameworks, but simply cleaning the code or directly running it usually gets rid of the warning. Otherwise it may have to do with using an older build of Xcode.
Second if I use: struct Repo: Glossy I get error that Repo doesn't conform to protocols Decodable and Encodable but the code is pasted from the example and there exist the methods init?(json: JSON) and func toJSON() -> JSON?
This means that your struct doesn't conform to both protocols. From the Glossy declaration:
/**
Convenience protocol for objects that can be
translated from and to JSON
*/
public protocol Glossy: Decodable, Encodable { }
So the Glossy protocol inherits both Decodable and Encodable, which means that you need to implement the protocol functions for both protocols, and not just toJSON() -> JSON?.
Then I tried to use struct Repo: Decodable and having this function for decoder: ...
You need to first declare the constant in the struct, and in the init deserialise the JSON and set the value to the constant:
struct Repo: Decodable {
let repoId: Int
init?(json: JSON) {
guard let repoId: Int = "id" <~~ json { else return nil }
self.repoId = repoId
}
}

Resources