diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d952fe..cbcd82d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,13 @@
**Note**: Gaps between patch versions are faulty/broken releases.
**Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice.
-0.0.1
+# 0.0.2
+
+- **New Feature**
+ - add `lensesFromInterface` (@leemhenson)
+ - add `lensesFromTuple` (@gcanti)
+ - add `prismsFromUnion` (@gcanti)
+
+# 0.0.1
Initial release
diff --git a/package.json b/package.json
index 82db6da..4d09f38 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "io-ts-types",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "A collection of runtime types for use with io-ts",
"files": ["lib"],
"main": "lib/index.js",
diff --git a/src/index.ts b/src/index.ts
index c38c287..0bc9e39 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -14,9 +14,11 @@ export { AnyStringPrism } from './monocle-ts/AnyStringPrism'
export { composeTypeWithPrism } from './monocle-ts/composeTypeWithPrism'
export { createRangePrism } from './monocle-ts/createRangePrism'
export { ISOStringDatePrism } from './monocle-ts/ISOStringDatePrism'
-export { lensesFromProps } from './monocle-ts/lensesFromProps'
+export { lensesFromInterface } from './monocle-ts/lensesFromInterface'
+export { lensesFromTuple } from './monocle-ts/lensesFromTuple'
export { NumberDatePrism } from './monocle-ts/NumberDatePrism'
export { NumberIntegerPrism } from './monocle-ts/NumberIntegerPrism'
+export { prismsFromUnion } from './monocle-ts/prismsFromUnion'
export { StringJSONPrism } from './monocle-ts/StringJSONPrism'
export { StringNumberPrism } from './monocle-ts/StringNumberPrism'
import * as TypePrismIso from './monocle-ts/TypePrismIso'
diff --git a/src/monocle-ts/lensesFromProps.ts b/src/monocle-ts/lensesFromInterface.ts
similarity index 75%
rename from src/monocle-ts/lensesFromProps.ts
rename to src/monocle-ts/lensesFromInterface.ts
index 0fc9faf..2d6ff80 100644
--- a/src/monocle-ts/lensesFromProps.ts
+++ b/src/monocle-ts/lensesFromInterface.ts
@@ -5,7 +5,7 @@ export type LensesFromProps
= t.In
[K in keyof P]: Lens
}
-export function lensesFromProps(i: t.InterfaceType
): LensesFromProps
{
+export function lensesFromInterface
(i: t.InterfaceType
): LensesFromProps
{
const r: any = {}
for (const k in i.props) {
r[k] = Lens.fromProp(k)
diff --git a/src/monocle-ts/lensesFromTuple.ts b/src/monocle-ts/lensesFromTuple.ts
new file mode 100644
index 0000000..6adedce
--- /dev/null
+++ b/src/monocle-ts/lensesFromTuple.ts
@@ -0,0 +1,50 @@
+import * as t from 'io-ts'
+import { Lens } from 'monocle-ts'
+
+export type LensesFromTuple5> = {
+ 'L0': Lens, t.TypeOf>
+ 'L1': Lens, t.TypeOf>
+ 'L2': Lens, t.TypeOf>
+ 'L3': Lens, t.TypeOf>
+ 'L4': Lens, t.TypeOf>
+}
+export type LensesFromTuple4> = {
+ 'L0': Lens, t.TypeOf>
+ 'L1': Lens, t.TypeOf>
+ 'L2': Lens, t.TypeOf>
+ 'L3': Lens, t.TypeOf>
+}
+export type LensesFromTuple3> = {
+ 'L0': Lens, t.TypeOf>
+ 'L1': Lens, t.TypeOf>
+ 'L2': Lens, t.TypeOf>
+}
+export type LensesFromTuple2> = {
+ 'L0': Lens, t.TypeOf>
+ 'L1': Lens, t.TypeOf>
+}
+export type LensesFromTuple1> = {
+ 'L0': Lens, t.TypeOf>
+}
+
+export function lensesFromTuple>(
+ type: T
+): LensesFromTuple5
+export function lensesFromTuple>(type: T): LensesFromTuple4
+export function lensesFromTuple>(type: T): LensesFromTuple3
+export function lensesFromTuple>(type: T): LensesFromTuple2
+export function lensesFromTuple>(type: T): LensesFromTuple1
+export function lensesFromTuple>(type: T): { [key: string]: Lens } {
+ const r: { [key: string]: Lens } = {}
+ for (let i = 0; i < type.types.length; i++) {
+ r['L' + i] = new Lens(
+ s => s[i],
+ a => s => {
+ const s2 = s.slice()
+ s2[i] = a
+ return s2
+ }
+ )
+ }
+ return r
+}
diff --git a/src/monocle-ts/prismsFromUnion.ts b/src/monocle-ts/prismsFromUnion.ts
new file mode 100644
index 0000000..20635d1
--- /dev/null
+++ b/src/monocle-ts/prismsFromUnion.ts
@@ -0,0 +1,39 @@
+import * as t from 'io-ts'
+import { Prism } from 'monocle-ts'
+
+export type PrismsFromUnion5> = {
+ 'P0': Prism, t.TypeOf>
+ 'P1': Prism, t.TypeOf>
+ 'P2': Prism, t.TypeOf>
+ 'P3': Prism, t.TypeOf>
+ 'P4': Prism, t.TypeOf>
+}
+export type PrismsFromUnion4> = {
+ 'P0': Prism, t.TypeOf>
+ 'P1': Prism, t.TypeOf>
+ 'P2': Prism, t.TypeOf>
+ 'P3': Prism, t.TypeOf>
+}
+export type PrismsFromUnion3> = {
+ 'P0': Prism, t.TypeOf>
+ 'P1': Prism, t.TypeOf>
+ 'P2': Prism, t.TypeOf>
+}
+export type PrismsFromUnion2> = {
+ 'P0': Prism, t.TypeOf>
+ 'P1': Prism, t.TypeOf>
+}
+
+export function prismsFromUnion>(
+ type: T
+): PrismsFromUnion5
+export function prismsFromUnion>(type: T): PrismsFromUnion4
+export function prismsFromUnion>(type: T): PrismsFromUnion3
+export function prismsFromUnion>(type: T): PrismsFromUnion2
+export function prismsFromUnion>(type: T): { [key: string]: Prism } {
+ const r: { [key: string]: Prism } = {}
+ for (let i = 0; i < type.types.length; i++) {
+ r['P' + i] = new Prism(s => t.validate(s, type.types[i]).toOption(), a => a)
+ }
+ return r
+}
diff --git a/test/index.ts b/test/index.ts
index b2eb3d4..47109a9 100644
--- a/test/index.ts
+++ b/test/index.ts
@@ -11,10 +11,13 @@ import {
StringNumberPrism,
StringJSONPrism,
DateFromNumber,
- JSONFromString
+ JSONFromString,
+ lensesFromInterface,
+ lensesFromTuple,
+ prismsFromUnion
} from '../src'
import * as t from 'io-ts'
-import { None, Some } from 'fp-ts/lib/Option'
+import { None, Some, none, some } from 'fp-ts/lib/Option'
import { Left, Right } from 'fp-ts/lib/Either'
import { fromSome, fromRight } from './helpers'
@@ -110,6 +113,31 @@ describe('monocle-ts', () => {
assert.strictEqual(fromSome(P.getOption('null')), null)
assert.deepEqual(fromSome(P.getOption('{"name":"Giulio"}')), { name: 'Giulio' })
})
+
+ it('lensesFromInterface', () => {
+ const Person = t.interface({
+ name: t.string,
+ age: t.number
+ })
+ const lenses = lensesFromInterface(Person)
+ assert.strictEqual(lenses.age.get({ name: 'Giulio', age: 43 }), 43)
+ })
+
+ it('lensesFromTuple', () => {
+ const Point = t.tuple([t.number, t.number])
+ const pointLenses = lensesFromTuple(Point)
+ assert.strictEqual(pointLenses.L1.get([100, 200]), 200)
+ assert.deepEqual(pointLenses.L0.set(50)([100, 200]), [50, 200])
+ })
+
+ it('prismsFromUnion', () => {
+ const RuntimeUnion = t.union([t.string, t.number])
+ const unionPrisms = prismsFromUnion(RuntimeUnion)
+ assert.deepEqual(unionPrisms.P0.getOption('a'), some('a'))
+ assert.deepEqual(unionPrisms.P0.getOption(1), none)
+ assert.deepEqual(unionPrisms.P1.getOption('a'), none)
+ assert.deepEqual(unionPrisms.P1.getOption(1), some(1))
+ })
})
describe('JSON', () => {