Skip to content

Commit 491fe1f

Browse files
committed
clarifying name change in tests. update documentation around entity direct subscript accessor
1 parent 6b6f40c commit 491fe1f

2 files changed

Lines changed: 8 additions & 11 deletions

File tree

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,6 @@ typealias Attributes = NoAttributes
348348
let favoriteColor: String = person[\.favoriteColor]
349349
```
350350

351-
NOTE: Because of support for computed properties that are not wrapped in `Attribute`, `TransformedAttribute`, or `ValidatedAttribute`, the compiler cannot always infer the type of thing you want back when using subscript attribute access. The following code is ambiguous about whether it should return a `String` or an `Attribute<String>`:
352-
```swift
353-
let favoriteColor = person[\.favoriteColor]
354-
```
355-
356351
#### `Transformer`
357352

358353
Sometimes you need to use a type that does not encode or decode itself in the way you need to represent it as a serialized JSON object. For example, the Swift `Foundation` type `Date` can encode/decode itself to `Double` out of the box, but you might want to represent dates as ISO 8601 compliant `String`s instead. The Foundation library `JSONDecoder` has a setting to make this adjustment, but for the sake of an example, you could create a `Transformer`.
@@ -391,14 +386,16 @@ You can also creator `Validators` and `ValidatedAttribute`s. A `Validator` is ju
391386

392387
#### Computed `Attribute`
393388

394-
You can add computed properties to your `EntityDescription.Attributes` struct if you would like to expose attributes that are not explicitly represented by the JSON. These computed properties do not have to be wrapped in `Attribute`, `ValidatedAttribute`, or `TransformedAttribute`. This allows computed attributes to be of types that are not `Codable`. Here's an example of how you might take the `Person[\.name]` attribute from the example above and create a `fullName` computed property.
389+
You can add computed properties to your `EntityDescription.Attributes` struct if you would like to expose attributes that are not explicitly represented by the JSON. These computed properties do not have to be wrapped in `Attribute`, `ValidatedAttribute`, or `TransformedAttribute`. This allows computed attributes to be of types that are not `Codable`. Here's an example of how you might take the `person[\.name]` attribute from the example above and create a `fullName` computed property.
395390

396391
```swift
397392
public var fullName: Attribute<String> {
398393
return name.map { $0.joined(separator: " ") }
399394
}
400395
```
401396

397+
If your computed property is wrapped in a `AttributeType` then you can still use the default subscript operator to access it (as would be the case with the `person[\.fullName]` example above). However, if you add a property to the `Attributes` `struct` that is not wrapped in an `AttributeType`, you must either access it from its full path (`person.attributes.newThing`) or with the "direct" subscript accessor (`person[direct: \.newThing]`). This keeps the subscript access unambiguous enough for the compiler to be helpful prior to explicitly casting, comparing, or storing the result.
398+
402399
### Copying `Entities`
403400
`Entity` is a value type, so copying is its default behavior. There are two common mutations you might want to make when copying an `Entity`:
404401
1. Assigning a new `Identifier` to the copy of an identified `Entity`.
@@ -593,7 +590,7 @@ extension EntityDescription1.Attributes {
593590
### Meta-Attributes
594591
This advanced feature may not ever be useful, but if you find yourself in the situation of dealing with an API that does not 100% follow the **SPEC** then you might find meta-attributes are just the thing to make your entities more natural to work with.
595592

596-
Suppose, for example, you are presented with the unfortunate situation where a piece of information you need is only available as part of the `Id` of an entity. Perhaps a user's `Id` is formatted "{integer}-{createdAt}" where "createdAt" is the unix timestamp when the user account was created. The following `UserDescription` will expose what you need as an attribute. Realistically, this code is still terrible for its error handling. Using a `Result` type and/or invariants would clean things up substantially.
593+
Suppose, for example, you are presented with the unfortunate situation where a piece of information you need is only available as part of the `Id` of an entity. Perhaps a user's `Id` is formatted "{integer}-{createdAt}" where "createdAt" is the unix timestamp when the user account was created. The following `UserDescription` will expose what you need as an attribute. Realistically, the following example code is still terrible for its error handling. Using a `Result` type and/or invariants would clean things up substantially.
597594

598595
```swift
599596
enum UserDescription: EntityDescription {

Tests/JSONAPITests/Computed Properties/ComputedPropertiesTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ class ComputedPropertiesTests: XCTestCase {
2727
let entity = decoded(type: TestType.self, data: computed_property_attribute)
2828

2929
XCTAssertEqual(entity[\.computed], "Sarah2")
30-
XCTAssertEqual(entity[direct: \.secretsOut], "shhhh")
30+
XCTAssertEqual(entity[direct: \.directSecretsOut], "shhhh")
3131
}
3232

3333
func test_ComputedNonAttributeAccess() {
3434
let entity = decoded(type: TestType.self, data: computed_property_attribute)
3535

36-
XCTAssertEqual(entity[direct: \.computed2], "Sarah2")
36+
XCTAssertEqual(entity[direct: \.directComputed], "Sarah2")
3737
}
3838

3939
func test_ComputedRelationshipAccess() {
@@ -56,11 +56,11 @@ extension ComputedPropertiesTests {
5656
return name.map { $0 + "2" }
5757
}
5858

59-
public var computed2: String {
59+
public var directComputed: String {
6060
return computed.value
6161
}
6262

63-
public var secretsOut: String {
63+
public var directSecretsOut: String {
6464
return secret.value
6565
}
6666
}

0 commit comments

Comments
 (0)