diff --git a/.changeset/tasty-bulldogs-share.md b/.changeset/tasty-bulldogs-share.md
new file mode 100644
index 000000000..dcec4de0e
--- /dev/null
+++ b/.changeset/tasty-bulldogs-share.md
@@ -0,0 +1,5 @@
+---
+"@effect/schema": patch
+---
+
+add BrandSchema, getOption
diff --git a/docs/modules/Parser.ts.md b/docs/modules/Parser.ts.md
index 86a8ca0fa..9f0333b50 100644
--- a/docs/modules/Parser.ts.md
+++ b/docs/modules/Parser.ts.md
@@ -20,6 +20,7 @@ Added in v1.0.0
- [decoding](#decoding)
- [decode](#decode)
- [decodeOrThrow](#decodeorthrow)
+ - [getOption](#getoption)
- [encoding](#encoding)
- [encode](#encode)
- [encodeOrThrow](#encodeorthrow)
@@ -100,6 +101,18 @@ export declare const decodeOrThrow: (
Added in v1.0.0
+## getOption
+
+**Signature**
+
+```ts
+export declare const getOption: (
+ schema: Schema
+) => (input: unknown, options?: AST.ParseOptions | undefined) => O.Option
+```
+
+Added in v1.0.0
+
# encoding
## encode
diff --git a/docs/modules/Schema.ts.md b/docs/modules/Schema.ts.md
index 390b33fc0..41eaa93f7 100644
--- a/docs/modules/Schema.ts.md
+++ b/docs/modules/Schema.ts.md
@@ -77,6 +77,7 @@ Added in v1.0.0
- [startsWith](#startswith)
- [trimmed](#trimmed)
- [model](#model)
+ - [BrandSchema (interface)](#brandschema-interface)
- [Schema (interface)](#schema-interface)
- [parsers](#parsers)
- [clamp](#clamp)
@@ -262,7 +263,7 @@ Schema + B -> Schema>
export declare const brand: (
brand: B,
options?: AnnotationOptions | undefined
-) => (self: Schema) => Schema
+) => (self: Schema) => BrandSchema
```
**Example**
@@ -481,8 +482,8 @@ using the provided decoding functions.
```ts
export declare const transformOrFail: (
to: Schema,
- decode: (input: A, options?: AST.ParseOptions | undefined) => Either,
- encode: (input: B, options?: AST.ParseOptions | undefined) => Either
+ decode: (input: A, options?: AST.ParseOptions | undefined) => E.Either,
+ encode: (input: B, options?: AST.ParseOptions | undefined) => E.Either
) => (self: Schema) => Schema
```
@@ -896,6 +897,16 @@ Added in v1.0.0
# model
+## BrandSchema (interface)
+
+**Signature**
+
+```ts
+export interface BrandSchema> extends Schema, Brand.Constructor {}
+```
+
+Added in v1.0.0
+
## Schema (interface)
**Signature**
diff --git a/docs/modules/index.ts.md b/docs/modules/index.ts.md
index 4656fcf6b..19ee0f8ce 100644
--- a/docs/modules/index.ts.md
+++ b/docs/modules/index.ts.md
@@ -21,6 +21,7 @@ Added in v1.0.0
- [encodeOrThrow](#encodeorthrow)
- [failure](#failure)
- [failures](#failures)
+ - [getOption](#getoption)
- [is](#is)
- [isFailure](#isfailure)
- [isSuccess](#issuccess)
@@ -118,6 +119,18 @@ export declare const failures: (
Added in v1.0.0
+## getOption
+
+**Signature**
+
+```ts
+export declare const getOption: (
+ schema: Schema
+) => (input: unknown, options?: ParseOptions | undefined) => Option
+```
+
+Added in v1.0.0
+
## is
**Signature**
diff --git a/src/Parser.ts b/src/Parser.ts
index d84f241e1..19d426151 100644
--- a/src/Parser.ts
+++ b/src/Parser.ts
@@ -2,20 +2,10 @@
* @since 1.0.0
*/
-import { isBoolean } from "@effect/data/Boolean"
import { pipe } from "@effect/data/Function"
-import { isNumber } from "@effect/data/Number"
import * as O from "@effect/data/Option"
-import {
- isBigint,
- isNever,
- isNotNullable,
- isObject,
- isRecord,
- isString,
- isSymbol,
- isUndefined
-} from "@effect/data/Predicate"
+import type { Option } from "@effect/data/Option"
+import * as P from "@effect/data/Predicate"
import * as RA from "@effect/data/ReadonlyArray"
import * as H from "@effect/schema/annotation/Hook"
import * as AST from "@effect/schema/AST"
@@ -48,6 +38,14 @@ export const decode = (
schema: Schema
): (input: unknown, options?: ParseOptions) => ParseResult => parserFor(schema).parse
+/**
+ * @category decoding
+ * @since 1.0.0
+ */
+export const getOption = (schema: Schema) =>
+ (input: unknown, options?: ParseOptions): Option =>
+ O.fromEither(parserFor(schema).parse(input, options))
+
/**
* @category decoding
* @since 1.0.0
@@ -139,26 +137,26 @@ const parserFor = (
(u): u is typeof ast.symbol => u === ast.symbol
)
case "UndefinedKeyword":
- return I.fromRefinement(I.makeSchema(ast), isUndefined)
+ return I.fromRefinement(I.makeSchema(ast), P.isUndefined)
case "VoidKeyword":
- return I.fromRefinement(I.makeSchema(ast), isUndefined)
+ return I.fromRefinement(I.makeSchema(ast), P.isUndefined)
case "NeverKeyword":
- return I.fromRefinement(I.makeSchema(ast), isNever)
+ return I.fromRefinement(I.makeSchema(ast), P.isNever)
case "UnknownKeyword":
case "AnyKeyword":
return make(I.makeSchema(ast), PR.success)
case "StringKeyword":
- return I.fromRefinement(I.makeSchema(ast), isString)
+ return I.fromRefinement(I.makeSchema(ast), P.isString)
case "NumberKeyword":
- return I.fromRefinement(I.makeSchema(ast), isNumber)
+ return I.fromRefinement(I.makeSchema(ast), P.isNumber)
case "BooleanKeyword":
- return I.fromRefinement(I.makeSchema(ast), isBoolean)
+ return I.fromRefinement(I.makeSchema(ast), P.isBoolean)
case "BigIntKeyword":
- return I.fromRefinement(I.makeSchema(ast), isBigint)
+ return I.fromRefinement(I.makeSchema(ast), P.isBigint)
case "SymbolKeyword":
- return I.fromRefinement(I.makeSchema(ast), isSymbol)
+ return I.fromRefinement(I.makeSchema(ast), P.isSymbol)
case "ObjectKeyword":
- return I.fromRefinement(I.makeSchema(ast), isObject)
+ return I.fromRefinement(I.makeSchema(ast), P.isObject)
case "Enums":
return I.fromRefinement(
I.makeSchema(ast),
@@ -166,7 +164,7 @@ const parserFor = (
)
case "TemplateLiteral": {
const regex = I.getTemplateLiteralRegex(ast)
- return I.fromRefinement(I.makeSchema(ast), (u): u is any => isString(u) && regex.test(u))
+ return I.fromRefinement(I.makeSchema(ast), (u): u is any => P.isString(u) && regex.test(u))
}
case "Tuple": {
const elements = ast.elements.map((e) => go(e.type))
@@ -285,7 +283,7 @@ const parserFor = (
}
case "TypeLiteral": {
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
- return I.fromRefinement(I.makeSchema(ast), isNotNullable)
+ return I.fromRefinement(I.makeSchema(ast), P.isNotNullable)
}
const propertySignaturesTypes = ast.propertySignatures.map((f) => go(f.type))
const indexSignatures = ast.indexSignatures.map((is) =>
@@ -294,7 +292,7 @@ const parserFor = (
return make(
I.makeSchema(ast),
(input: unknown, options) => {
- if (!isRecord(input)) {
+ if (!P.isRecord(input)) {
return PR.failure(PR.type(unknownRecord, input))
}
const output: any = {}
@@ -417,7 +415,7 @@ const parserFor = (
if (len > 0) {
// if there is at least one key then input must be an object
- if (isRecord(input)) {
+ if (P.isRecord(input)) {
for (let i = 0; i < len; i++) {
const name = ownKeys[i]
const buckets = searchTree.keys[name].buckets
diff --git a/src/Schema.ts b/src/Schema.ts
index 58d93e7df..2761e302c 100644
--- a/src/Schema.ts
+++ b/src/Schema.ts
@@ -3,6 +3,8 @@
*/
import type { Brand } from "@effect/data/Brand"
+import { RefinedConstructorsTypeId } from "@effect/data/Brand"
+import * as E from "@effect/data/Either"
import { pipe } from "@effect/data/Function"
import type { Option } from "@effect/data/Option"
import type { Predicate, Refinement } from "@effect/data/Predicate"
@@ -12,11 +14,13 @@ import * as AST from "@effect/schema/AST"
import type { ParseOptions } from "@effect/schema/AST"
import * as DataDate from "@effect/schema/data/Date"
import * as N from "@effect/schema/data/Number"
-import * as O from "@effect/schema/data/Object"
+import * as DataObject from "@effect/schema/data/Object"
import * as DataOption from "@effect/schema/data/Option"
import * as SRA from "@effect/schema/data/ReadonlyArray"
import * as S from "@effect/schema/data/String"
+import { formatErrors } from "@effect/schema/formatter/Tree"
import * as I from "@effect/schema/internal/common"
+import * as P from "@effect/schema/Parser"
import type { ParseResult } from "@effect/schema/ParseResult"
/**
@@ -82,7 +86,7 @@ export const enums = (
export const instanceOf: any>(
constructor: A,
annotationOptions?: AnnotationOptions