# Propery wrapper decoding difference between \`singleValueContainer\` and \`init(from: Decoder)\`

**URL:** <https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918>\
**Category:** Using Swift\
**Created:** [September 9, 2021, 3:23pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918 "2021-09-09T15:23:04Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![jflan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jflan/32/15474_2.png) [@jflan](https://forums.swift.org/u/jflan)\
**Post date:** [September 9, 2021, 3:23pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/1 "2021-09-09T15:23:04Z")

</div>

I ran into a difference in the decoding behavior of property wrappers based on the specifics of how it implements `init(from decoder: Decoder)` that I didn't expect.

If implemented with `singleValueContainer` everything behaves as I'd expect:

```swift
extension ContainerWrapper: Decodable where Wrapped: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        self.wrappedValue = try container.decode(Wrapped.self)
    }
}

```

If implemented by calling `Wrapped(from: decoder)` then wrapped dictionaries apply the `.convertFromSnakeCase` conversion to their `String` keys. (full example code below)

```swift
extension DirectWrapper: Decodable where Wrapped: Decodable {
    init(from decoder: Decoder) throws {
        self.wrappedValue = try Wrapped(from: decoder)
    }
}

```

Can anyone explain why those two implementations would behave differently?

This code demonstrates the issue:

```swift
import Foundation

let jsonData = #"{ "dictionary": { "some_key": 1 } }"#.data(using: .utf8)!

// MARK: Property wrappers

@propertyWrapper
struct ContainerWrapper<Wrapped> {
    let wrappedValue: Wrapped
}

extension ContainerWrapper: Decodable where Wrapped: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        self.wrappedValue = try container.decode(Wrapped.self)
    }
}

@propertyWrapper
struct DirectWrapper<Wrapped> {
    let wrappedValue: Wrapped
}

extension DirectWrapper: Decodable where Wrapped: Decodable {
    init(from decoder: Decoder) throws {
        self.wrappedValue = try Wrapped(from: decoder)
    }
}

// MARK: Subjects

struct ContainerSubject: Decodable {
    @ContainerWrapper
    var dictionary: [String: Int]
}

struct DirectSubject: Decodable {
    @DirectWrapper
    var dictionary: [String: Int]
}

// MARK: Tests

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

// prints: ["some_key": 1]
print(try decoder.decode(ContainerSubject.self, from: jsonData).dictionary)

// prints: ["someKey": 1]
print(try decoder.decode(DirectSubject.self, from: jsonData).dictionary)

```

---

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [September 9, 2021, 6:34pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/2 "2021-09-09T18:34:59Z")

</div>

We had this very behavior reported by @buscarini for one of our libraries here: [Custom date decoding issue · Issue #23 · pointfreeco/swift-tagged · GitHub](https://github.com/pointfreeco/swift-tagged/issues/23)

I'm not sure if he filed a bug, but it wouldn't hurt to submit one, unless there's some explanation for this behavior being intentional.

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [September 9, 2021, 7:42pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/3 "2021-09-09T19:42:46Z")

</div>

When `ContainerWrapper` asks `decoder` to decode a `[String: Int]`, that goes through a special-case code path. It calls [this overload of `decode`](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L2111-L2114):

```swift
    public func decode<T : Decodable>(_ type: T.Type) throws -> T {
        try expectNonNull(type)
        return try self.unbox(self.storage.topContainer, as: type)!
    }

```

which calls [this overload of `unbox`](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L2485-L2487):

```swift
    func unbox<T : Decodable>(_ value: Any, as type: T.Type) throws -> T? {
        return try unbox_(value, as: type) as? T
    }

```

which calls [`unbox_`](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L2489-L2513):

```swift
    func unbox_(_ value: Any, as type: Decodable.Type) throws -> Any? {
        if type == Date.self || type == NSDate.self {
            return try self.unbox(value, as: Date.self)
        } else if type == Data.self || type == NSData.self {
            return try self.unbox(value, as: Data.self)
        } else if type == URL.self || type == NSURL.self {
            guard let urlString = try self.unbox(value, as: String.self) else {
                return nil
            }

            guard let url = URL(string: urlString) else {
                throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath,
                                                                        debugDescription: "Invalid URL string."))
            }
            return url
        } else if type == Decimal.self || type == NSDecimalNumber.self {
            return try self.unbox(value, as: Decimal.self)
        } else if let stringKeyedDictType = type as? _JSONStringDictionaryDecodableMarker.Type {
            return try self.unbox(value, as: stringKeyedDictType)
        } else {
            self.storage.push(container: value)
            defer { self.storage.popContainer() }
            return try type.init(from: self)
        }
    }

```

which detects the conformance of `[String: Int]` to `_JSONStringDictionaryDecodableMarker` and so calls [this overload of `unbox`](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L2466-L2483):

```swift
    func unbox<T>(_ value: Any, as type: _JSONStringDictionaryDecodableMarker.Type) throws -> T? {
        guard !(value is NSNull) else { return nil }

        var result = [String : Any]()
        guard let dict = value as? NSDictionary else {
            throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
        }
        let elementType = type.elementType
        for (key, value) in dict {
            let key = key as! String
            self.codingPath.append(_JSONKey(stringValue: key, intValue: nil))
            defer { self.codingPath.removeLast() }

            result[key] = try unbox_(value, as: elementType)
        }

        return result as? T
    }

```

which iterates over the keys of the internal representation (an `NSDictionary`) without performing snake-case conversion.

When `DirectWrapper` calls the `init(from: Decoder)` method of `[String: Int]`, it's calling [this initializer](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/core/Codable.swift#L5569-L5579):

```swift
  public init(from decoder: Decoder) throws {
    self.init()

    if Key.self == String.self {
      // The keys are Strings, so we should be able to expect a keyed container.
      let container = try decoder.container(keyedBy: _DictionaryCodingKey.self)
      for key in container.allKeys {
        let value = try container.decode(Value.self, forKey: key)
        self[key.stringValue as! Key] = value
      }
    } else if Key.self == Int.self {
    ... many more lines omitted ...

```

which (because `Key` is `String`) asks the decoder for a `KeyedDecodingContainer` by calling [this method](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L1251-L1264):

```swift
    public func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> {
        guard !(self.storage.topContainer is NSNull) else {
            throw DecodingError.valueNotFound(KeyedDecodingContainer<Key>.self,
                                              DecodingError.Context(codingPath: self.codingPath,
                                                                    debugDescription: "Cannot get keyed decoding container -- found null value instead."))
        }

        guard let topContainer = self.storage.topContainer as? [String : Any] else {
            throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: self.storage.topContainer)
        }

        let container = _JSONKeyedDecodingContainer<Key>(referencing: self, wrapping: topContainer)
        return KeyedDecodingContainer(container)
    }

```

which calls [the `init` of `_JSONKeyedDecodingContainer`](https://github.com/apple/swift/blob/845205b4407cb1e50ebe69a4d1174714338337c3/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L1339-L1356):

```swift
    init(referencing decoder: __JSONDecoder, wrapping container: [String : Any]) {
        self.decoder = decoder
        switch decoder.options.keyDecodingStrategy {
        case .useDefaultKeys:
            self.container = container
        case .convertFromSnakeCase:
            // Convert the snake case keys in the container to camel case.
            // If we hit a duplicate key after conversion, then we'll use the first one we saw. Effectively an undefined behavior with JSON dictionaries.
            self.container = Dictionary(container.map {
                key, value in (JSONDecoder.KeyDecodingStrategy._convertFromSnakeCase(key), value)
            }, uniquingKeysWith: { (first, _) in first })
        case .custom(let converter):
            self.container = Dictionary(container.map {
                key, value in (converter(decoder.codingPath + [_JSONKey(stringValue: key, intValue: nil)]).stringValue, value)
            }, uniquingKeysWith: { (first, _) in first })
        }
        self.codingPath = decoder.codingPath
    }

```

which performs snake-case conversion. This is the **only** way to get snake-case conversion while decoding.

Since `ContainerWrapper` doesn't end up going through a keyed container, it doesn't get snake-case conversion.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [September 9, 2021, 7:45pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/4 "2021-09-09T19:45:46Z")

</div>

This isn't a bug, but a consequence of the flow of events when you call methods on a container (owned by a `Decoder` as opposed to passing control directly to `Wrapped`.

1. When you call `try container.decode(Wrapped.self)`, execution passes to the `decode` method on the container, which gives the container (and the decoder it belongs to) an opportunity to act on the specific value of the type passed in. [`__JSONDecoder.decode<T>(_:T.Type)`](https://github.com/apple/swift-corelibs-foundation/blob/b3b87b6328325b639032bdc92e384f33f0beef0e/Darwin/Foundation-swiftoverlay/JSONEncoder.swift#L2111), the method being called here, passes `T.Type` down to [`__JSONDecoder.unbox(_:as:)`](https://github.com/apple/swift-corelibs-foundation/blob/b3b87b6328325b639032bdc92e384f33f0beef0e/Darwin/Foundation-swiftoverlay/JSONEncoder.swift#L2489), which inspects the given type to override certain behaviors. In this case, it looks for a dictionary type ([as a `_JSONStringDictionaryDecodableMarker`](https://github.com/apple/swift-corelibs-foundation/blob/b3b87b6328325b639032bdc92e384f33f0beef0e/Darwin/Foundation-swiftoverlay/JSONEncoder.swift#L2506)) to be able to apply the decoding strategy. Once the strategy is applied, the decoder ends up calling [`T.init(from:)`](https://github.com/apple/swift-corelibs-foundation/blob/b3b87b6328325b639032bdc92e384f33f0beef0e/Darwin/Foundation-swiftoverlay/JSONEncoder.swift#L2511), which in this case is `Wrapped.init(from:)`
2. When you call `Wrapped.init(from:)` _directly_, you bypass all of this and pass execution over to `Wrapped` immediately. This means that the container/`Decoder` never got a chance to intercept execution, and apply any of its own strategies to the underlying data

In general, it's preferred that you decode directly from containers for this reason (to give the `Decoder` a chance to massage the data into the form you need), but there's room in certain very niche cases for your second strategy.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [September 9, 2021, 7:46pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/5 "2021-09-09T19:46:41Z")

</div>

Ah, @mayoff beat me to it while I was typing this up. Exactly the right analysis.

---

<div class="post-metadata">

**Author:** ![jflan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jflan/32/15474_2.png) [@jflan](https://forums.swift.org/u/jflan)\
**Post date:** [September 9, 2021, 9:13pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/6 "2021-09-09T21:13:28Z")

</div>

Thank you both for the responses!

Is this considered a bug in `JSONDecoder`, or is calling `init(from: Decoder)` directly in this case considered a programming error?

I had assumed they were effectively interchangeable. Is there any way to better message that calling `init(from: Decoder)` directly is _probably_ a mistake?

> [@itaiferber](#):
>
> In general, it's preferred that you decode directly from containers for this reason (to give the `Decoder` a chance to massage the data into the form you need), but there's room in certain very niche cases for your second strategy.

Does this advise also apply to encoding?

Is is better to prefer

```swift
func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    try container.encode(wrappedValue)
}

```

over

```swift
func encode(to encoder: Encoder) throws {
    try wrappedValue.encode(to: encoder)
}

```

?

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [September 9, 2021, 10:51pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/7 "2021-09-09T22:51:02Z")

</div>

> [@jflan](#):
>
> Is this considered a bug in `JSONDecoder` , or is calling `init(from: Decoder)` directly in this case considered a programming error?

I definitely wouldn't consider it a bug, but I also don't know if I'd go so far as to call it "programmer error" necessarily:

- A _bug_ implies that there's something to correct or fix, but there's nothing technically wrong with the code: in a way, you're getting exactly what you ask for — execution passes to the entity you're calling directly.
  - Even if we call this a bug, there isn't anything terribly actionable: there's no way to turn the code from calling `Wapped.init(from:)` into code the `Decoder` is running without entirely subverting what you've written. But I would consider that equally, if not _more_ surprising (i.e. I would be _very_ surprised if the compiler somehow transformed `try Wrapped(from: decoder)` into something that didn't directly call `Wrapped.init(from:)`)

- It's also not _necessarily_ an error: this is a sort of escape hatch from calling into the `Decoder`, and I can imagine some cases for calling code this way (potentially around some overlapping/nested objects encoding into the same container as `self`), but it would be _very_ niche

That being said, it is certainly surprising, and I know I can dig up at least one or two more threads from the past where this has come up.

> [@jflan](#):
>
> Is there any way to better message that calling `init(from: Decoder)` directly is _probably_ a mistake?

Short of a warning, I'm not sure how we'd do this, since this is valid code. The initializer requirement has to be publicly exposed so `Decoder`s themselves can call it. The downside to a warning is that in a _valid_ use-case (where you really know what you're doing), there'd be no good way to silence it. (There _are_ schemes that Swift could implement, but that's way out in the weeds, and in general, we prefer warnings to have in-source solutions — there needs to be an obvious "right" way to write the code to disable the warning, but in this case there wouldn't be.)

> [@jflan](#):
>
> Does this advise also apply to encoding?

Yes, for the exact same reasons. Your second code snippet doesn't afford an `Encoder` the opportunity to intercept the encoding type and apply strategies. So even in the case where you're encoding only a single value, you should use a container in the majority of cases.

---

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [September 9, 2021, 10:52pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/8 "2021-09-09T22:52:27Z")

</div>

Perhaps some more documentation is in order?

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 27, 2023, 12:05am UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/9 "2023-01-27T00:05:25Z")

</div>

Yes, the bug here is that the effects of using `singleValueContainer` are not documented, i.e. what difference does it make to what's actually encoded? Does it provide benefits that directly encoding the stored value does not have? /cc @Tony_Parker @Philippe_Hausler

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [January 27, 2023, 1:19am UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/11 "2023-01-27T01:19:36Z")

</div>

I deleted a previous post which I believe was a misunderstanding of your question. To be clear, are you asking about the difference between

```swift
func encode(to encoder: Encoder) throws {
    try wrappedValue.encode(to: encoder)
}

```

and

```swift
func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    try container.encode(wrappedValue)
}

```

?

If so, functionally: for **most** types, there is no fundamental difference between these two; at the encoded representation layer, for an arbitrary type `T`, there will be no difference between the two forms.

_However:_ there _is_ a difference between the sequence of events that happen for these two forms, and in the second case, the container is what gets to call `wrappedValue.encode(to: encoder)`. This means that theoretically, the container (and the underlying `Encoder`) has the _opportunity_ to run code before and after the request to encode, affording the `Encoder` the opportunity to inspect `wrappedValue`, and make decisions about how to encode it in a way that's most appropriate for the format. This means that for specific types, you may see a difference between the two forms.

(FWIW, this behavior is not specific to `singleValueContainer` — any encode call through any container gives the `Encoder` the opportunity to inspect the value being encoded. This is also the difference, for instance, between asking for a keyed container and encoding properties one by one, instead of collection a dictionary of values and calling `dict.encode(to: encoder)`.)

* * *

ETA: to hopefully be even clearer, all of this basically boils down to

```swift
protocol P {
    func f()
}

struct S {
    static func f(_ p: P) {
        // Maybe some code...
        p.f()
        // Maybe some code...
    }
}

let p: P = ...

p.f()
// vs. 
S.f(p)

```

Calling `p.f()` doesn't involve `S` at all, outside of what the implementation of the function might itself do. Calling `s.f(p)` defers to `S` immediately, and it may do whatever it wants (but it _generally_ only just calls `p.f()` itself).

---

<div class="post-metadata">

**Author:** ![jflan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jflan/32/15474_2.png) [@jflan](https://forums.swift.org/u/jflan)\
**Post date:** [January 27, 2023, 2:06am UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/12 "2023-01-27T02:06:45Z")

</div>

As an example, `Decimal` is encoded wildly diffrently by `JSONEncoder` depending on which approach you use:

 ![image](https://global.discourse-cdn.com/swift/original/3X/8/0/80a1772d744b0cbec8a507ee80b412535cf976e6.jpeg)

and `Data` won't respect `.dataEncodingStrategy`:

 ![image](https://global.discourse-cdn.com/swift/original/3X/a/0/a07c5b6498154eb120b183d1f95dff8c29bc754b.jpeg)

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 27, 2023, 4:10am UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/13 "2023-01-27T04:10:23Z")

</div>

> [@itaiferber](#):
>
> _However:_ there _is_ a difference between the sequence of events that happen for these two forms, and in the second case,

In other words, there is no clear semantic difference between these things, and _if_ `singleValueContainer` were documented, it could only be at best as pseudocode for this sequence of events you've laid out. There's no way to know if I should do things one way or the other in general; it depends on lots of factors about which I can't reason locally.

This is not an abstraction, and it's no wonder it's not documented, because the effects are very difficult to describe clearly.

I appreciate your effort to explain it here, but to be clear I wasn't asking for help. I was characterizing the problem.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [January 27, 2023, 6:09pm UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/14 "2023-01-27T18:09:41Z")

</div>

> [@dabrahams](#):
>
> I wasn't asking for help. I was characterizing the problem.

Ah, understood!

> [@dabrahams](#):
>
> it's no wonder it's not documented, because the effects are very difficult to describe clearly

Agreed — documenting this requires striking a delicate balance between sufficiently motivating the use case to not use a container, and a lot of the more esoteric details that might follow from it (especially without using an example from a concrete `Encoder`).

> [@dabrahams](#):
>
> There's no way to know if I should do things one way or the other in general

Fortunately, at least, a guideline on this is at least easier to give: in the 99.999% use case, you should be using a container for all of your encoding. If you find yourself writing `x.encode(to: encoder)` inside of your own `encode(to:)`, it's much more likely than not that you're not going to get the results you want or expect.

There's definitely room to make this clearer. If there were a way to leverage the compiler to help with this too, that would also be interesting.

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 28, 2023, 12:37am UTC](https://forums.swift.org/t/propery-wrapper-decoding-difference-between-singlevaluecontainer-and-init-from-decoder/51918/15 "2023-01-28T00:37:27Z")

</div>

> [@itaiferber](#):
>
> Fortunately, at least, a guideline on this is at least easier to give: in the 99.999% use case, you should be using a container for all of your encoding. If you find yourself writing `x.encode(to: encoder)` inside of your own `encode(to:)`, it's much more likely than not that you're not going to get the results you want or expect.
> 
> There's definitely room to make this clearer. If there were a way to leverage the compiler to help with this too, that would also be interesting.

Even just putting that guideline in the documentation for `singleValueContainer` would be a huge help.
