Skip to content
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

JSONSerialization re-encodes Decimal as Double #1115

Open
blindspotbounty opened this issue Jan 9, 2025 · 0 comments
Open

JSONSerialization re-encodes Decimal as Double #1115

blindspotbounty opened this issue Jan 9, 2025 · 0 comments

Comments

@blindspotbounty
Copy link

I am using JSONSerialization to sort keys for arbitrary JSON represented as String:

func sortedJSON(_ string: String) -> String? {
    guard let data = string.data(using: .utf8),
          let json = try? JSONSerialization.jsonObject(with: data, options: []),
          let sortedData = try? JSONSerialization.data(withJSONObject: json, options: [.sortedKeys])
    else {
        return nil
    }

    return .init(data: sortedData, encoding: .utf8)
}

/// example of usage
enum DecimalContainting: Codable {
    case decimal(Decimal)
}

let decimal = DecimalContainting.decimal(Decimal(string: "129.9")!)
let jsonEncoder = JSONEncoder()
let data = try jsonEncoder.encode(decimal)

let jsonUnsortedString = String(data: data, encoding: .utf8)

let jsonSortedString = jsonUnsortedString.flatMap { sortedJSON($0) }
print(jsonUnsortedString)
print(jsonSortedString)

The output is surprisingly different for sorted and unsorted data:

Optional("{\"decimal\":{\"_0\":129.9}}")
Optional("{\"decimal\":{\"_0\":129.90000000000001}}")

Notably, this happens on MacOS but if I run the same code on linux, the output is the same for both:

Optional("{\"decimal\":{\"_0\":129.9}}")
Optional("{\"decimal\":{\"_0\":129.9}}")

Swift version macOS:

$ swift --version
swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)

Swift version Linux:

$ swift --version
Swift version 6.0.1 (swift-6.0.1-RELEASE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant