1 package io.atlassian.fugue.optic;
2
3 import io.atlassian.fugue.Either;
4 import io.atlassian.fugue.Eithers;
5 import io.atlassian.fugue.Option;
6
7 import java.util.function.Function;
8
9
10
11
12 public final class Prism<S, A> extends PPrism<S, S, A, A> {
13
14 final PPrism<S, S, A, A> pPrism;
15
16 public Prism(final PPrism<S, S, A, A> pPrism) {
17 this.pPrism = pPrism;
18 }
19
20 @Override public Either<S, A> getOrModify(final S s) {
21 return pPrism.getOrModify(s);
22 }
23
24 @Override public S reverseGet(final A a) {
25 return pPrism.reverseGet(a);
26 }
27
28 @Override public Option<A> getOption(final S s) {
29 return pPrism.getOption(s);
30 }
31
32
33
34
35
36
37
38
39 public final <C, D> Setter<S, C> composeSetter(final Setter<A, C> other) {
40 return new Setter<>(pPrism.composeSetter(other.pSetter));
41 }
42
43
44
45
46 public final <C, D> Traversal<S, C> composeTraversal(final Traversal<A, C> other) {
47 return new Traversal<>(pPrism.composeTraversal(other.pTraversal));
48 }
49
50
51
52
53 public final <C, D> Optional<S, C> composeOptional(final Optional<A, C> other) {
54 return new Optional<>(pPrism.composeOptional(other.pOptional));
55 }
56
57
58
59
60 public final <C, D> Optional<S, C> composeLens(final Lens<A, C> other) {
61 return new Optional<>(pPrism.composeLens(other.pLens));
62 }
63
64
65
66
67 public final <C> Prism<S, C> composePrism(final Prism<A, C> other) {
68 return new Prism<>(pPrism.composePrism(other.pPrism));
69 }
70
71
72
73
74 public final <C, D> Prism<S, C> composeIso(final Iso<A, C> other) {
75 return new Prism<>(pPrism.composeIso(other.pIso));
76 }
77
78
79
80
81
82
83
84
85 @Override public final Setter<S, A> asSetter() {
86 return new Setter<>(pPrism.asSetter());
87 }
88
89
90
91
92 @Override public final Traversal<S, A> asTraversal() {
93 return new Traversal<>(pPrism.asTraversal());
94 }
95
96
97
98
99 @Override public final Optional<S, A> asOptional() {
100 return new Optional<>(pPrism.asOptional());
101 }
102
103 public static <S> Prism<S, S> id() {
104 return new Prism<>(pId());
105 }
106
107 public static <S, A> Prism<S, A> prism(final Function<S, Option<A>> getOption, final Function<A, S> reverseGet) {
108 return new Prism<>(new PPrism<S, S, A, A>() {
109
110 @Override public Either<S, A> getOrModify(final S s) {
111 return getOption.apply(s).fold(() -> Either.<S, A> left(s), Eithers.<S, A> toRight());
112 }
113
114 @Override public S reverseGet(final A a) {
115 return reverseGet.apply(a);
116 }
117
118 @Override public Option<A> getOption(final S s) {
119 return getOption.apply(s);
120 }
121 });
122 }
123
124 }