-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What is needed to support encoding #2
Comments
Hi @lightsprint09 sorry for the delay answering (somehow I am not receiving notifications on this project). Any help is welcome, so if you want to toil at it, I would be happy to review or help. Most of the architecture for The problem is that adopting and developing for |
Sounds good. Would you mind if I set up Travis CI? |
That sounds interesting. I have never done it myself in an OpenSource project from Github. As far as I understand it is a CI system to run your test on every commit. But what will it actually entail? Do we have to keep a specific Git structure, who has access to its configuration?, etc. |
@lightsprint09 I managed to take a look at the state of the code this weekend and the major problem with the In simple words:
Thus, there are several options we can pursue:
|
How is it possible to Writer further ahead? Using the same stream |
Well, it is not yet implemented, but I suppose that if the user decide to write in row 10 and they are currently in row 5; the Writing empty rows is actually quite common in CSV files. |
let stream = OutputStream(url: ...)
let encoder = CSVEncoder(stream: stream)
let codable = ["A", "B", "C"]
try encoder.encode(codable) How would I define where top write. I would expect to write at the end of there stream? |
As you can see, there is an incompatibility from the sequential expectations of
|
Ok. I see. Seems like I don't understand the Codable implementation correctly. Can you show me an example how one would implement |
Don't despair, the Compiler Generation ExampleLet's suppose you have a CSV file listing students in a school. Each row is a student and the columns are: struct Student: Encodable {
let name: String
let age: Int
let hasPet: Bool
} Then you can simple use the let students = [
Student(name: "Heidrun", age: 12, hasPet: true),
Student(name: "Gudrun", age: 11, hasPet: false)
]
let encoder = CSVEncoder()
encoder.encode(students) Generated CodeYou are letting the compiler generate the extension Student {
private enum CodingKeys: String, CodingKey {
case name, age, hasPet
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.age, forKey: .age)
try container.encode(self.hasPet, forKey: .hasPet)
}
} But you are also using the internal extension Array {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
for element in self {
try container.encode(element) // where an element is a student
}
}
} All TogetherSo the actions when
The rows/students will be sequentially encoded, so we wouldn't have the "randomly-accessible writes" problems there. However, nowhere is defined the order of the row's fields (i.e. the students properties). The
If the previous problem is solved correctly. The program will most likely matched the |
The previous example was the simple/naive one. Let's suppose the framework user is savvy on the Unkeyed Fields ExampleLets have the same struct Student: Encodable {
let name: String
let age: Int
let hasPet: Bool
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(self.name)
try container.encode(self.age)
try container.encode(self.hasPet)
}
} In this example, we achieve the best performance since we are creating a sequential container ( Keyed Fields Examples (Int Values)We could have decided to use a struct Student: Encodable {
let name: String
let age: Int
let hasPet: Bool
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.name)
try container.encode(self.age)
try container.encode(self.hasPet)
}
private enum CodingKeys: Int, CodingKey {
case name = 2
case age = 1
case hasPet = 0
}
} Interestingly, here we are defining the order of the fields within a row; and weirdly the definition order is not matching the encoding order. Here we encounter the first "randomly-access write" problem. Albeit, in a low scale, since it only pertain to a single row.
|
Yes and no. In CSV files, the column order implies meaning, therefore the user must know exactly the order of the generated outcome. It cannot be "execution magic". Also, the order must be consistent between several That is however not the major problem, I believe we can find an "easy solution" for that. |
Unordered Rows ExampleLets suppose a similar case (same students listing), but now the row positions have meanings. Lets say: struct Class: Encodable {
var heidrun: Student
var gutrun: Student
var alexander: Student
var sigrid: Student
private enum CodingKeys: Int, CodingKey {
case alexander = 1
case gutrun = 2
case heidrun = 3
case sigrid = 4
}
} The compiler generated code will start encoding on |
Hi @lightsprint09, Just as a heads-up, I have reimplemented the I will probably write the Cheers |
Hey @dehesa, sounds awesome. I will have a look |
Alright, I am happy to announce that after some hard laboring, I have the first encodable implementation. It still needs polishing and support for other buffering strategy, but it currently works 😄 You can find it in the |
Could I help you supporting Encodable?
The text was updated successfully, but these errors were encountered: