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

Add propertyOrder option to ParseOptions to control the order of … #2926

Merged
merged 2 commits into from
Jun 5, 2024

Conversation

gcanti
Copy link
Contributor

@gcanti gcanti commented Jun 5, 2024

…keys in the output, closes #2925

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

The propertyOrder option provides control over the order of object fields in the output. This feature is particularly useful when the sequence of keys is important for the consuming processes or when maintaining the input order enhances readability and usability.

By default, the propertyOrder option is set to "none". This means that the internal system decides the order of keys to optimize parsing speed. The order of keys in this mode should not be considered stable, and it's recommended not to rely on key ordering as it may change in future updates without notice.

Setting propertyOrder to "input" ensures that the keys are ordered as they appear in the input during the decoding/encoding process.

Example (Synchronous Decoding)

import { Schema } from "@effect/schema"

const schema = Schema.Struct({
  a: Schema.Number,
  b: Schema.Literal("b"),
  c: Schema.Number
})

// Decoding an object synchronously without specifying the property order
console.log(Schema.decodeUnknownSync(schema)({ b: "b", c: 2, a: 1 }))
// Output decided internally: { b: 'b', a: 1, c: 2 }

// Decoding an object synchronously while preserving the order of properties as in the input
console.log(
  Schema.decodeUnknownSync(schema)(
    { b: "b", c: 2, a: 1 },
    { propertyOrder: "original" }
  )
)
// Output preserving input order: { b: 'b', c: 2, a: 1 }

Example (Asynchronous Decoding)

import { ParseResult, Schema } from "@effect/schema"
import type { Duration } from "effect"
import { Effect } from "effect"

// Function to simulate an asynchronous process within the schema
const effectify = (duration: Duration.DurationInput) =>
  Schema.Number.pipe(
    Schema.transformOrFail(Schema.Number, {
      decode: (x) =>
        Effect.sleep(duration).pipe(Effect.andThen(ParseResult.succeed(x))),
      encode: ParseResult.succeed
    })
  )

// Define a structure with asynchronous behavior in each field
const schema = Schema.Struct({
  a: effectify("200 millis"),
  b: effectify("300 millis"),
  c: effectify("100 millis")
}).annotations({ concurrency: 3 })

// Decoding data asynchronously without preserving order
Schema.decode(schema)({ a: 1, b: 2, c: 3 })
  .pipe(Effect.runPromise)
  .then(console.log)
// Output decided internally: { c: 3, a: 1, b: 2 }

// Decoding data asynchronously while preserving the original input order
Schema.decode(schema)({ a: 1, b: 2, c: 3 }, { propertyOrder: "original" })
  .pipe(Effect.runPromise)
  .then(console.log)
// Output preserving input order: { a: 1, b: 2, c: 3 }

Related

@gcanti gcanti added the schema label Jun 5, 2024
Copy link

changeset-bot bot commented Jun 5, 2024

🦋 Changeset detected

Latest commit: 51840b8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
@effect/schema Patch
@effect/cli Patch
@effect/experimental Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/platform Patch
@effect/rpc-http Patch
@effect/rpc Patch
@effect/sql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gcanti gcanti merged commit 4c6bc7f into main Jun 5, 2024
12 checks passed
@gcanti gcanti deleted the schema/2925 branch June 5, 2024 18:11
@github-actions github-actions bot mentioned this pull request Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

From Discord: Clarification on onExcessProperty: preserve Behavior: Key Order Not Maintained
1 participant