├── .dockerignore
├── .gitattributes
├── .gitignore
├── .yamllint
├── CHANGELOG.md
├── Dockerfile
├── LICENSE.txt
├── Makefile
├── README.md
├── doc
├── README.md
├── edoc-info
├── erlang.png
├── index.html
├── lenses.jpg
├── modules-frame.html
├── optic.html
├── optic.md
├── optic_array.html
├── optic_array.md
├── optic_dict.html
├── optic_dict.md
├── optic_gb_sets.html
├── optic_gb_sets.md
├── optic_gb_trees.html
├── optic_gb_trees.md
├── optic_generic.html
├── optic_generic.md
├── optic_lists.html
├── optic_lists.md
├── optic_maps.html
├── optic_maps.md
├── optic_orddict.html
├── optic_orddict.md
├── optic_ordsets.html
├── optic_ordsets.md
├── optic_path.html
├── optic_path.md
├── optic_proplists.html
├── optic_proplists.md
├── optic_sets.html
├── optic_sets.md
├── optic_tuples.html
├── optic_tuples.md
├── overview-summary.html
├── overview.edoc
└── stylesheet.css
├── docker-compose.yml
├── include
└── optic_tuples.hrl
├── rebar.config
├── rebar.lock
├── requirements.txt
├── src
├── optic.app.src
├── optic.erl
├── optic_array.erl
├── optic_dict.erl
├── optic_gb_sets.erl
├── optic_gb_trees.erl
├── optic_generic.erl
├── optic_lists.erl
├── optic_maps.erl
├── optic_orddict.erl
├── optic_ordsets.erl
├── optic_path.erl
├── optic_proplists.erl
├── optic_sets.erl
└── optic_tuples.erl
└── test
├── test_optic.erl
├── test_optic_array.erl
├── test_optic_dict.erl
├── test_optic_gb_sets.erl
├── test_optic_gb_trees.erl
├── test_optic_generic.erl
├── test_optic_lists.erl
├── test_optic_maps.erl
├── test_optic_orddict.erl
├── test_optic_ordsets.erl
├── test_optic_path.erl
├── test_optic_proplists.erl
├── test_optic_sets.erl
└── test_optic_tuples.erl
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Docker build instructions.
2 | Dockerfile
3 | .dockerignore
4 |
5 | # Revision control.
6 | .git/
7 | **/.gitignore
8 |
9 | # Vim files.
10 | tags
11 | **/*.sw[po]
12 |
13 | # Build tools in base image.
14 | ./rebar3
15 |
16 | # Local build artifacts.
17 | ./_build
18 | .virtualenv
19 | log
20 | logs
21 | test/.rebar3
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Erlang build and crash files.
2 | *.beam
3 | *.o
4 | *.plt
5 | .erlang.cookie
6 | .idea
7 | _build
8 | ebin
9 | erl_crash.dump
10 | log
11 | logs
12 | rebar3
13 | rebar3.crashdump
14 | .rebar3
15 |
16 | # CI secrets.
17 | codeship.aes
18 | deploy/dockercfg.json
19 | deploy/env.env
20 | config/test.config
21 |
22 | # Optional python dependencies.
23 | .virtualenv
24 |
25 | # Optional node.js dependencies.
26 | node_modules/
27 | package-lock.json
28 |
29 | # Vim files.
30 | *.swo
31 | *.swp
32 | tags
33 |
--------------------------------------------------------------------------------
/.yamllint:
--------------------------------------------------------------------------------
1 | ignore: |
2 | /_build
3 | /.virtualenv
4 | /docker/.volumes
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [3.1.0] - 2019-04-28
11 | ### Added
12 | - The `optic_array` module was added to work with the corresponding
13 | container.
14 |
15 | ## [3.0.0] - 2019-04-26
16 | ### Changed
17 | - The argument order of `optic:map/3`, `optic:fold/4`, `optic:mapfold/4` and
18 | `optic:put/3` was changed to be the same as the corresponding lists module
19 | order; subject last.
20 |
21 | ## [2.1.0] - 2019-04-26
22 | ### Added
23 | - The `optic_dict`, `optic_orddict`, `optic_gb_trees`, `optic_sets`,
24 | `optic_ordsets` and `optic_gb_sets` modules were added to work with the
25 | corresponding containers.
26 |
27 | ## [2.0.0] - 2019-02-24
28 | ### Added
29 | - The `optic:wrap/2` and `optic:wrap/3` functions were added to enable
30 | modifying optics without exposing the internal representation.
31 | - The `optic:chain/1` function was added to enable explicit optic composition.
32 | - The `optic:is_optic/1` function was added.
33 | - The `optic:create/3` optic wrapper was exposed as a public interface.
34 | - The `optic:lax/1` optic wrapper was exposed as a public interface.
35 | - The `optic:error/1` generic optic was added.
36 | - The `optic:filter/1` generic optic was added.
37 | - The `optic:require/1` generic optic was added.
38 |
39 | ### Changed
40 | - The `optic:from/1` function was renamed to `optic:merge/1` to better
41 | distinguish it from chaining.
42 | - The `optic_generic:id/0` optic was moved to `optic:id/0`.
43 | - The internal `optic:'%extend'/3` interface was renamed to `optic:variations/3`.
44 |
45 | ## [1.0.0] - 2019-02-20
46 | ### Added
47 | - Initial release.
48 |
49 | [Unreleased]: https://github.com/jkrukoff/optic/compare/v3.1.0...HEAD
50 | [3.1.0]: https://github.com/jkrukoff/optic/compare/v3.0.0...v3.1.0
51 | [3.0.0]: https://github.com/jkrukoff/optic/compare/v2.1.0...v3.0.0
52 | [2.1.0]: https://github.com/jkrukoff/optic/compare/v2.0.0...v2.1.0
53 | [2.0.0]: https://github.com/jkrukoff/optic/compare/v1.0.0...v2.0.0
54 | [1.0.0]: https://github.com/jkrukoff/optic/releases/tag/v1.0.0
55 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM erlang:21
2 |
3 | # Install build and test dependencies.
4 | # python3-pip: for installing python build dependencies.
5 | RUN set -xe && apt-get update && apt-get install -y python3-pip
6 |
7 | RUN mkdir -p /usr/src/app
8 | WORKDIR /usr/src/app
9 |
10 | COPY ./requirements.txt ./
11 | RUN pip3 install -r requirements.txt
12 |
13 | COPY . ./
14 | RUN make compile
15 |
16 | ENTRYPOINT ["make"]
17 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | MAKEFLAGS += --warn-undefined-variables
2 | .DEFAULT_GOAL := all
3 |
4 | PYTHON := python3
5 | REBAR ?= ${if ${wildcard ./rebar3}, ./rebar3, rebar3}
6 |
7 | .PHONY: all
8 | ## Build everything.
9 | all: test-unit doc
10 | ${MAKE} compile
11 |
12 | .PHONY: clean
13 | ## Delete intermediate files.
14 | clean:
15 | ${REBAR} clean -a
16 |
17 | .PHONY: compile
18 | ## Compile all profiles.
19 | compile:
20 | ${REBAR} compile
21 | ${REBAR} as test compile
22 |
23 | .PHONY: doc
24 | ## Build documentation.
25 | doc: require-pic2plot $(addsuffix .png,$(basename $(wildcard doc/*.pic)))
26 | ${REBAR} edoc
27 | ${REBAR} as markdown edoc
28 |
29 | doc/%.png: doc/%.pic
30 | pic2plot --font-size=0.010 --bitmap-size=4096x4096 --line-width=0.00097656 -Tpng $< > $@
31 |
32 | .SILENT: help
33 | .PHONY: help
34 | ## This help screen.
35 | help:
36 | # Extracts help from the Makefile itself, printing help for any rule
37 | # which matches the defined regular expression and that has a double
38 | # hash (##) comment on the line above.
39 | printf "Available Targets:\n\n"
40 | awk '/^[a-zA-Z\-\_0-9]+:/ { \
41 | helpMessage = match(lastLine, /^## (.*)/); \
42 | if (helpMessage) { \
43 | helpCommand = substr($$1, 0, index($$1, ":")); \
44 | helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
45 | printf "%-18s %s\n", helpCommand, helpMessage; \
46 | } \
47 | } \
48 | { lastLine = $$0 }' ${MAKEFILE_LIST}
49 |
50 | rebar.lock: rebar.config
51 | ${REBAR} update
52 | ${REBAR} unlock
53 | ${REBAR} upgrade
54 |
55 | REQUIREMENTS = $(addprefix require-,pic2plot yamllint virtualenv)
56 |
57 | .PHONY: ${REQUIREMENTS}
58 | ${REQUIREMENTS}: what=$(patsubst require-%,%,$@)
59 | ${REQUIREMENTS}: require-%:
60 | @which $(what) > /dev/null || \
61 | (printf "%s%s%s\n" "$$(tput setaf 3)" '"$(what)" is required, please install.' "$$(tput sgr0)"; exit 1)
62 |
63 | rebar3:
64 | curl -o rebar3 https://s3.amazonaws.com/rebar3/rebar3
65 | chmod 755 rebar3
66 |
67 | .PHONY: test
68 | ## Run all test suites.
69 | test: test-unit test-integration
70 |
71 | .PHONY: test-integration
72 | ## Run the integration test suite.
73 | test-integration:
74 | envsubst < config/test.config.template > config/test.config
75 | if ! ${REBAR} as test do ct --config=config/test.config; then \
76 | grep -lr 'CT Error Notification' _build/test/logs/ | xargs -n 1 html2text; \
77 | fi
78 |
79 | .PHONY: test-unit
80 | ## Run the unit test suite.
81 | test-unit: require-yamllint
82 | ${REBAR} as prod dialyzer
83 | ${REBAR} as test do dialyzer, eunit, proper, geas #, lint
84 | yamllint -s .
85 |
86 | .virtualenv: requirements.txt
87 | ${MAKE} require-virtualenv
88 | virtualenv --clear --download --always-copy -p "$$(which ${PYTHON})" .virtualenv
89 | .virtualenv/bin/pip install --force-reinstall --upgrade pip setuptools wheel
90 | .virtualenv/bin/pip install -r requirements.txt
91 | @printf "\n\n%s%s%s\n" "$$(tput setaf 3)" "To activate virtualenv run: source .virtualenv/bin/activate" "$$(tput sgr0)"
92 |
--------------------------------------------------------------------------------
/doc/edoc-info:
--------------------------------------------------------------------------------
1 | %% encoding: UTF-8
2 | {application,optic}.
3 | {modules,[optic,optic_array,optic_dict,optic_gb_sets,optic_gb_trees,
4 | optic_generic,optic_lists,optic_maps,optic_orddict,optic_ordsets,
5 | optic_path,optic_proplists,optic_sets,optic_tuples]}.
6 |
--------------------------------------------------------------------------------
/doc/erlang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkrukoff/optic/4aa37630fd37e43af3ccfa0c947f9c8a27d77154/doc/erlang.png
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The optic application
5 |
6 |
7 |
8 |
9 |
10 |
11 | This page uses frames
12 | Your browser does not accept frames.
13 | You should go to the non-frame version instead.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/doc/lenses.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jkrukoff/optic/4aa37630fd37e43af3ccfa0c947f9c8a27d77154/doc/lenses.jpg
--------------------------------------------------------------------------------
/doc/modules-frame.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The optic application
5 |
6 |
7 |
8 | Modules
9 |
24 |
25 |
--------------------------------------------------------------------------------
/doc/optic_array.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_array
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_array
13 |
14 | A set of optics specific to arrays.
15 |
16 |
17 |
18 | A set of optics specific to arrays.
19 |
20 | all/0
21 | all/1
22 | Focus on all values of an array.
23 | nth/1
24 | nth/2
25 | Focus on the nth value of an array.
26 |
27 |
28 |
29 |
30 |
31 |
34 | See also: all/1 .
35 |
36 |
37 |
38 |
all(Options) -> optic:optic()
39 |
40 |
Options : Common optic options.
41 |
42 |
returns: An opaque optic record.
43 |
44 | Focus on all values of an array.
45 |
46 | Example:
47 |
48 | > optic:get([optic_array:all()], array:from_list([1,2,3])).
49 | {ok,[1,2,3]}
50 |
51 |
52 |
56 | See also: nth/2 .
57 |
58 |
59 |
60 |
nth(N, Options) -> optic:optic()
61 |
62 |
N : The index of the array value to focus on.
63 | Options : Common optic options.
64 |
65 |
returns: An opaque optic record.
66 |
67 | Focus on the nth value of an array. Like lists, but unlike the
68 | standard array operations, indexing begins at 1.
69 |
70 | Example:
71 |
72 | > optic:get([optic_array:nth(1)], array:from_list([1,2,3])).
73 | {ok,[1]}
74 |
75 |
76 |
77 | Generated by EDoc
78 |
79 |
80 |
--------------------------------------------------------------------------------
/doc/optic_array.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_array #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to arrays.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 | ## Function Details ##
23 |
24 |
25 |
26 | ### all/0 ###
27 |
28 |
29 | all() -> optic:optic()
30 |
31 |
32 |
33 | __See also:__ [all/1](#all-1).
34 |
35 |
36 |
37 | ### all/1 ###
38 |
39 |
40 | all(Options) -> optic:optic()
41 |
42 |
43 |
44 |
45 | `Options`: Common optic options.
46 |
47 | returns: An opaque optic record.
48 |
49 | Focus on all values of an array.
50 |
51 | Example:
52 |
53 | ```
54 | > optic:get([optic_array:all()], array:from_list([1,2,3])).
55 | {ok,[1,2,3]}
56 | ```
57 |
58 |
59 |
60 | ### nth/1 ###
61 |
62 |
63 | nth(N) -> optic:optic()
64 |
65 |
66 |
67 |
68 | __See also:__ [nth/2](#nth-2).
69 |
70 |
71 |
72 | ### nth/2 ###
73 |
74 |
75 | nth(N, Options) -> optic:optic()
76 |
77 |
78 |
79 |
80 | `N`: The index of the array value to focus on. `Options`: Common optic options.
81 |
82 | returns: An opaque optic record.
83 |
84 | Focus on the nth value of an array. Like lists, but unlike the
85 | standard array operations, indexing begins at 1.
86 |
87 | Example:
88 |
89 | ```
90 | > optic:get([optic_array:nth(1)], array:from_list([1,2,3])).
91 | {ok,[1]}
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/doc/optic_dict.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_dict
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_dict
13 |
14 | A set of optics specific to dicts.
15 |
16 |
17 |
18 | A set of optics specific to dicts.
19 |
20 |
38 |
39 |
40 |
41 |
42 |
45 | See also: values/1 .
46 |
47 |
48 |
52 | See also: values/1 .
53 |
54 |
55 |
59 | See also: association/2 .
60 |
61 |
62 |
63 |
association(Key, Options) -> optic:optic()
64 |
65 |
Key : The key to focus on.
66 | Options : Common optic options.
67 |
68 |
returns: An opaque optic record.
69 |
70 | Focus on the association for a dict key. An association is the
71 | tuple of a dict key and value. If the key is modified, the optic is
72 | no longer well behaved.
73 |
74 | Example:
75 |
76 | > optic:get([optic_dict:association(first)],
77 | dict:from_list([{first, 1}, {second, 2}])).
78 | {ok,[{first,1}]}
79 |
80 |
81 |
84 | See also: associations/1 .
85 |
86 |
87 |
88 |
associations(Options) -> optic:optic()
89 |
90 |
Options : Common optic options.
91 |
92 |
returns: An opaque optic record.
93 |
94 | Focus on all associations of a dict. An association is a tuple of
95 | the key and value for each entry.
96 |
97 | Example:
98 |
99 | > optic:get([optic_dict:associations()],
100 | dict:from_list([{first, 1}, {second, 2}])).
101 | {ok,[{first,1},{second,2}]}
102 |
103 |
104 |
108 | See also: key/2 .
109 |
110 |
111 |
112 |
key(Key, Options) -> optic:optic()
113 |
114 |
Key : The key to focus on.
115 | Options : Common optic options.
116 |
117 |
returns: An opaque optic record.
118 |
119 | Focus on the value of a dict key.
120 |
121 | Example:
122 |
123 | > optic:get([optic_dict:key(first)],
124 | dict:from_list([{first, 1}, {second, 2}])).
125 | {ok,[1]}
126 |
127 |
128 |
131 | See also: keys/1 .
132 |
133 |
134 |
135 |
keys(Options) -> optic:optic()
136 |
137 |
Options : Common optic options.
138 |
139 |
returns: An opaque optic record.
140 |
141 | Focus on all keys of a dict.
142 |
143 | Example:
144 |
145 | > optic:get([optic_dict:keys()],
146 | dict:from_list([{first, 1}, {second, 2}])).
147 | {ok,[first,second]}
148 |
149 |
150 |
153 | See also: values/1 .
154 |
155 |
156 |
157 |
values(Options) -> optic:optic()
158 |
159 |
Options : Common optic options.
160 |
161 |
returns: An opaque optic record.
162 |
163 | Focus on all values of a dict.
164 |
165 | Example:
166 |
167 | > optic:get([optic_dict:values()],
168 | dict:from_list([{first, 1}, {second, 2}])).
169 | {ok,[1,2]}
170 |
171 |
172 |
173 | Generated by EDoc
174 |
175 |
176 |
--------------------------------------------------------------------------------
/doc/optic_dict.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_dict #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to dicts.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | ## Function Details ##
26 |
27 |
28 |
29 | ### all/0 ###
30 |
31 |
32 | all() -> optic:optic()
33 |
34 |
35 |
36 | __See also:__ [values/1](#values-1).
37 |
38 |
39 |
40 | ### all/1 ###
41 |
42 |
43 | all(Options) -> optic:optic()
44 |
45 |
46 |
47 |
48 | __See also:__ [values/1](#values-1).
49 |
50 |
51 |
52 | ### association/1 ###
53 |
54 |
55 | association(Key) -> optic:optic()
56 |
57 |
58 |
59 |
60 | __See also:__ [association/2](#association-2).
61 |
62 |
63 |
64 | ### association/2 ###
65 |
66 |
67 | association(Key, Options) -> optic:optic()
68 |
69 |
70 |
71 |
72 | `Key`: The key to focus on. `Options`: Common optic options.
73 |
74 | returns: An opaque optic record.
75 |
76 | Focus on the association for a dict key. An association is the
77 | tuple of a dict key and value. If the key is modified, the optic is
78 | no longer well behaved.
79 |
80 | Example:
81 |
82 | ```
83 | > optic:get([optic_dict:association(first)],
84 | dict:from_list([{first, 1}, {second, 2}])).
85 | {ok,[{first,1}]}
86 | ```
87 |
88 |
89 |
90 | ### associations/0 ###
91 |
92 |
93 | associations() -> optic:optic()
94 |
95 |
96 |
97 | __See also:__ [associations/1](#associations-1).
98 |
99 |
100 |
101 | ### associations/1 ###
102 |
103 |
104 | associations(Options) -> optic:optic()
105 |
106 |
107 |
108 |
109 | `Options`: Common optic options.
110 |
111 | returns: An opaque optic record.
112 |
113 | Focus on all associations of a dict. An association is a tuple of
114 | the key and value for each entry.
115 |
116 | Example:
117 |
118 | ```
119 | > optic:get([optic_dict:associations()],
120 | dict:from_list([{first, 1}, {second, 2}])).
121 | {ok,[{first,1},{second,2}]}
122 | ```
123 |
124 |
125 |
126 | ### key/1 ###
127 |
128 |
129 | key(Key) -> optic:optic()
130 |
131 |
132 |
133 |
134 | __See also:__ [key/2](#key-2).
135 |
136 |
137 |
138 | ### key/2 ###
139 |
140 |
141 | key(Key, Options) -> optic:optic()
142 |
143 |
144 |
145 |
146 | `Key`: The key to focus on. `Options`: Common optic options.
147 |
148 | returns: An opaque optic record.
149 |
150 | Focus on the value of a dict key.
151 |
152 | Example:
153 |
154 | ```
155 | > optic:get([optic_dict:key(first)],
156 | dict:from_list([{first, 1}, {second, 2}])).
157 | {ok,[1]}
158 | ```
159 |
160 |
161 |
162 | ### keys/0 ###
163 |
164 |
165 | keys() -> optic:optic()
166 |
167 |
168 |
169 | __See also:__ [keys/1](#keys-1).
170 |
171 |
172 |
173 | ### keys/1 ###
174 |
175 |
176 | keys(Options) -> optic:optic()
177 |
178 |
179 |
180 |
181 | `Options`: Common optic options.
182 |
183 | returns: An opaque optic record.
184 |
185 | Focus on all keys of a dict.
186 |
187 | Example:
188 |
189 | ```
190 | > optic:get([optic_dict:keys()],
191 | dict:from_list([{first, 1}, {second, 2}])).
192 | {ok,[first,second]}
193 | ```
194 |
195 |
196 |
197 | ### values/0 ###
198 |
199 |
200 | values() -> optic:optic()
201 |
202 |
203 |
204 | __See also:__ [values/1](#values-1).
205 |
206 |
207 |
208 | ### values/1 ###
209 |
210 |
211 | values(Options) -> optic:optic()
212 |
213 |
214 |
215 |
216 | `Options`: Common optic options.
217 |
218 | returns: An opaque optic record.
219 |
220 | Focus on all values of a dict.
221 |
222 | Example:
223 |
224 | ```
225 | > optic:get([optic_dict:values()],
226 | dict:from_list([{first, 1}, {second, 2}])).
227 | {ok,[1,2]}
228 | ```
229 |
230 |
--------------------------------------------------------------------------------
/doc/optic_gb_sets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_gb_sets
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_gb_sets
13 |
14 | A set of optics specific to gb_sets.
15 |
16 |
17 |
18 | A set of optics specific to gb_sets.
19 |
20 | all/0
21 | all/1
22 | Focus on all elements of a gb_set.
23 |
24 |
25 |
26 |
27 |
28 |
31 | See also: all/1 .
32 |
33 |
34 |
35 |
all(Options) -> optic:optic()
36 |
37 |
Options : Common optic options.
38 |
39 |
returns: An opaque optic record.
40 |
41 | Focus on all elements of a gb_set.
42 |
43 | Example:
44 |
45 | > optic:get([optic_gb_sets:all()], gb_sets:from_list([1,2,3])).
46 | {ok,[1,2,3]}
47 |
48 |
49 |
50 | Generated by EDoc
51 |
52 |
53 |
--------------------------------------------------------------------------------
/doc/optic_gb_sets.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_gb_sets #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to gb_sets.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 | all/0 all/1
16 | Focus on all elements of a gb_set.
17 |
18 |
19 |
20 |
21 | ## Function Details ##
22 |
23 |
24 |
25 | ### all/0 ###
26 |
27 |
28 | all() -> optic:optic()
29 |
30 |
31 |
32 | __See also:__ [all/1](#all-1).
33 |
34 |
35 |
36 | ### all/1 ###
37 |
38 |
39 | all(Options) -> optic:optic()
40 |
41 |
42 |
43 |
44 | `Options`: Common optic options.
45 |
46 | returns: An opaque optic record.
47 |
48 | Focus on all elements of a gb_set.
49 |
50 | Example:
51 |
52 | ```
53 | > optic:get([optic_gb_sets:all()], gb_sets:from_list([1,2,3])).
54 | {ok,[1,2,3]}
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/doc/optic_gb_trees.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_gb_trees
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_gb_trees
13 |
14 | A set of optics specific to gb_trees.
15 |
16 |
17 |
18 | A set of optics specific to gb_trees.
19 |
20 |
38 |
39 |
40 |
41 |
42 |
45 | See also: values/1 .
46 |
47 |
48 |
52 | See also: values/1 .
53 |
54 |
55 |
59 | See also: association/2 .
60 |
61 |
62 |
63 |
association(Key, Options) -> optic:optic()
64 |
65 |
Key : The key to focus on.
66 | Options : Common optic options.
67 |
68 |
returns: An opaque optic record.
69 |
70 | Focus on the association for a gb_tree key. An association is the
71 | tuple of a gb_tree key and value. If the key is modified, the optic is
72 | no longer well behaved.
73 |
74 | Example:
75 |
76 | > optic:get([optic_gb_trees:association(first)],
77 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
78 | {ok,[{first,1}]}
79 |
80 |
81 |
84 | See also: associations/1 .
85 |
86 |
87 |
88 |
associations(Options) -> optic:optic()
89 |
90 |
Options : Common optic options.
91 |
92 |
returns: An opaque optic record.
93 |
94 | Focus on all associations of a gb_tree. An association is a tuple of
95 | the key and value for each entry.
96 |
97 | Example:
98 |
99 | > optic:get([optic_gb_trees:associations()],
100 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
101 | {ok,[{first,1},{second,2}]}
102 |
103 |
104 |
108 | See also: key/2 .
109 |
110 |
111 |
112 |
key(Key, Options) -> optic:optic()
113 |
114 |
Key : The key to focus on.
115 | Options : Common optic options.
116 |
117 |
returns: An opaque optic record.
118 |
119 | Focus on the value of a gb_tree key.
120 |
121 | Example:
122 |
123 | > optic:get([optic_gb_trees:key(first)],
124 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
125 | {ok,[1]}
126 |
127 |
128 |
131 | See also: keys/1 .
132 |
133 |
134 |
135 |
keys(Options) -> optic:optic()
136 |
137 |
Options : Common optic options.
138 |
139 |
returns: An opaque optic record.
140 |
141 | Focus on all keys of a gb_tree.
142 |
143 | Example:
144 |
145 | > optic:get([optic_gb_trees:keys()],
146 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
147 | {ok,[first,second]}
148 |
149 |
150 |
153 | See also: values/1 .
154 |
155 |
156 |
157 |
values(Options) -> optic:optic()
158 |
159 |
Options : Common optic options.
160 |
161 |
returns: An opaque optic record.
162 |
163 | Focus on all values of a gb_tree.
164 |
165 | Example:
166 |
167 | > optic:get([optic_gb_trees:values()],
168 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
169 | {ok,[1,2]}
170 |
171 |
172 |
173 | Generated by EDoc
174 |
175 |
176 |
--------------------------------------------------------------------------------
/doc/optic_gb_trees.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_gb_trees #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to gb_trees.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | ## Function Details ##
26 |
27 |
28 |
29 | ### all/0 ###
30 |
31 |
32 | all() -> optic:optic()
33 |
34 |
35 |
36 | __See also:__ [values/1](#values-1).
37 |
38 |
39 |
40 | ### all/1 ###
41 |
42 |
43 | all(Options) -> optic:optic()
44 |
45 |
46 |
47 |
48 | __See also:__ [values/1](#values-1).
49 |
50 |
51 |
52 | ### association/1 ###
53 |
54 |
55 | association(Key) -> optic:optic()
56 |
57 |
58 |
59 |
60 | __See also:__ [association/2](#association-2).
61 |
62 |
63 |
64 | ### association/2 ###
65 |
66 |
67 | association(Key, Options) -> optic:optic()
68 |
69 |
70 |
71 |
72 | `Key`: The key to focus on. `Options`: Common optic options.
73 |
74 | returns: An opaque optic record.
75 |
76 | Focus on the association for a gb_tree key. An association is the
77 | tuple of a gb_tree key and value. If the key is modified, the optic is
78 | no longer well behaved.
79 |
80 | Example:
81 |
82 | ```
83 | > optic:get([optic_gb_trees:association(first)],
84 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
85 | {ok,[{first,1}]}
86 | ```
87 |
88 |
89 |
90 | ### associations/0 ###
91 |
92 |
93 | associations() -> optic:optic()
94 |
95 |
96 |
97 | __See also:__ [associations/1](#associations-1).
98 |
99 |
100 |
101 | ### associations/1 ###
102 |
103 |
104 | associations(Options) -> optic:optic()
105 |
106 |
107 |
108 |
109 | `Options`: Common optic options.
110 |
111 | returns: An opaque optic record.
112 |
113 | Focus on all associations of a gb_tree. An association is a tuple of
114 | the key and value for each entry.
115 |
116 | Example:
117 |
118 | ```
119 | > optic:get([optic_gb_trees:associations()],
120 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
121 | {ok,[{first,1},{second,2}]}
122 | ```
123 |
124 |
125 |
126 | ### key/1 ###
127 |
128 |
129 | key(Key) -> optic:optic()
130 |
131 |
132 |
133 |
134 | __See also:__ [key/2](#key-2).
135 |
136 |
137 |
138 | ### key/2 ###
139 |
140 |
141 | key(Key, Options) -> optic:optic()
142 |
143 |
144 |
145 |
146 | `Key`: The key to focus on. `Options`: Common optic options.
147 |
148 | returns: An opaque optic record.
149 |
150 | Focus on the value of a gb_tree key.
151 |
152 | Example:
153 |
154 | ```
155 | > optic:get([optic_gb_trees:key(first)],
156 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
157 | {ok,[1]}
158 | ```
159 |
160 |
161 |
162 | ### keys/0 ###
163 |
164 |
165 | keys() -> optic:optic()
166 |
167 |
168 |
169 | __See also:__ [keys/1](#keys-1).
170 |
171 |
172 |
173 | ### keys/1 ###
174 |
175 |
176 | keys(Options) -> optic:optic()
177 |
178 |
179 |
180 |
181 | `Options`: Common optic options.
182 |
183 | returns: An opaque optic record.
184 |
185 | Focus on all keys of a gb_tree.
186 |
187 | Example:
188 |
189 | ```
190 | > optic:get([optic_gb_trees:keys()],
191 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
192 | {ok,[first,second]}
193 | ```
194 |
195 |
196 |
197 | ### values/0 ###
198 |
199 |
200 | values() -> optic:optic()
201 |
202 |
203 |
204 | __See also:__ [values/1](#values-1).
205 |
206 |
207 |
208 | ### values/1 ###
209 |
210 |
211 | values(Options) -> optic:optic()
212 |
213 |
214 |
215 |
216 | `Options`: Common optic options.
217 |
218 | returns: An opaque optic record.
219 |
220 | Focus on all values of a gb_tree.
221 |
222 | Example:
223 |
224 | ```
225 | > optic:get([optic_gb_trees:values()],
226 | gb_trees:from_orddict([{first, 1}, {second, 2}])).
227 | {ok,[1,2]}
228 | ```
229 |
230 |
--------------------------------------------------------------------------------
/doc/optic_generic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_generic
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_generic
13 |
14 | A set of generic optics that can be applied to multiple container
15 | types.
16 |
17 |
18 |
19 | A set of generic optics that can be applied to multiple container
20 | types.
21 |
22 | Intended both as a convenience and to support optic creation from
23 | parsed paths in optic_path.
24 |
25 | Because of the ambiguous types they support, these optics do not
26 | support the standard optic options. Instead, they always skip
27 | unexpected types and never create missing values.
28 |
29 | index/1
30 | Focus on an element of a list like container.
31 | key/1
32 | Focus on the value of many different key/value like mappings.
33 |
34 |
35 |
36 |
37 |
38 |
39 |
index(Index) -> optic:optic()
40 |
Index = non_neg_integer()
41 |
Index : The one based index of the element to focus on.
42 |
43 |
returns: An opaque optic record.
44 |
45 | Focus on an element of a list like container. Indexing begins at 1.
46 | Understands how to focus on lists and tuples. Does not support the
47 | usual optic options.
48 |
49 | Example:
50 |
51 | > optic:get([optic_generic:index(3)], [1, 2, 3]).
52 | {ok,[3]}
53 |
54 |
55 |
56 |
key(Key) -> optic:optic()
57 |
58 |
Key : The key to focus on.
59 |
60 |
returns: An opaque optic record.
61 |
62 | Focus on the value of many different key/value like mappings.
63 | Understands how to focus on maps, property lists, dicts, orddicts
64 | and gb_trees. Does not support the usual optic options.
65 |
66 | Example:
67 |
68 | > optic:get([optic_generic:key(first)], #{first => 1}).
69 | {ok,[1]}
70 |
71 |
72 |
73 | Generated by EDoc
74 |
75 |
76 |
--------------------------------------------------------------------------------
/doc/optic_generic.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_generic #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of generic optics that can be applied to multiple container
9 | types.
10 |
11 |
12 |
13 | ## Description ##
14 |
15 | Intended both as a convenience and to support optic creation from
16 | parsed paths in optic_path.
17 |
18 | Because of the ambiguous types they support, these optics do not
19 | support the standard optic options. Instead, they always skip
20 | unexpected types and never create missing values.
21 |
22 | ## Function Index ##
23 |
24 |
25 | index/1
26 | Focus on an element of a list like container. key/1
27 | Focus on the value of many different key/value like mappings.
28 |
29 |
30 |
31 |
32 | ## Function Details ##
33 |
34 |
35 |
36 | ### index/1 ###
37 |
38 |
39 | index(Index) -> optic:optic()
40 |
41 |
42 | Index = non_neg_integer()
43 |
44 | `Index`: The one based index of the element to focus on.
45 |
46 | returns: An opaque optic record.
47 |
48 | Focus on an element of a list like container. Indexing begins at 1.
49 | Understands how to focus on lists and tuples. Does not support the
50 | usual optic options.
51 |
52 | Example:
53 |
54 | ```
55 | > optic:get([optic_generic:index(3)], [1, 2, 3]).
56 | {ok,[3]}
57 | ```
58 |
59 |
60 |
61 | ### key/1 ###
62 |
63 |
64 | key(Key) -> optic:optic()
65 |
66 |
67 |
68 |
69 | `Key`: The key to focus on.
70 |
71 | returns: An opaque optic record.
72 |
73 | Focus on the value of many different key/value like mappings.
74 | Understands how to focus on maps, property lists, dicts, orddicts
75 | and gb_trees. Does not support the usual optic options.
76 |
77 | Example:
78 |
79 | ```
80 | > optic:get([optic_generic:key(first)], #{first => 1}).
81 | {ok,[1]}
82 | ```
83 |
84 |
--------------------------------------------------------------------------------
/doc/optic_lists.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_lists
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_lists
13 |
14 | A set of optics specific to lists.
15 |
16 |
17 |
18 | A set of optics specific to lists.
19 |
20 | all/0
21 | all/1
22 | Focus on all elements of a list.
23 | head/0
24 | head/1
25 | Focus on the head of a list.
26 | nth/1
27 | nth/2
28 | Focus on the nth element of a list.
29 | tail/0
30 | tail/1
31 | Focus on the tail of a list.
32 |
33 |
34 |
35 |
36 |
37 |
40 | See also: all/1 .
41 |
42 |
43 |
44 |
all(Options) -> optic:optic()
45 |
46 |
Options : Common optic options.
47 |
48 |
returns: An opaque optic record.
49 |
50 | Focus on all elements of a list.
51 |
52 | Example:
53 |
54 | > optic:get([optic_lists:all()], [1,2,3]).
55 | {ok,[1,2,3]}
56 |
57 |
58 |
61 | See also: head/1 .
62 |
63 |
64 |
65 |
head(Options) -> optic:optic()
66 |
67 |
Options : Common optic options.
68 |
69 |
returns: An opaque optic record.
70 |
71 | Focus on the head of a list. The list must have at least one
72 | element to have a head.
73 |
74 | Example:
75 |
76 | > optic:get([optic_lists:head()], [1,2,3]).
77 | {ok,[1]}
78 |
79 |
80 |
84 | See also: nth/2 .
85 |
86 |
87 |
88 |
nth(N, Options) -> optic:optic()
89 |
90 |
N : The index of the list element to focus on.
91 | Options : Common optic options.
92 |
93 |
returns: An opaque optic record.
94 |
95 | Focus on the nth element of a list. As with lists:nth/2
, indexing
96 | begins at 1.
97 |
98 | Example:
99 |
100 | > optic:get([optic_lists:nth(1)], [1,2,3]).
101 | {ok,[1]}
102 |
103 |
104 |
107 | See also: tail/1 .
108 |
109 |
110 |
111 |
tail(Options) -> optic:optic()
112 |
113 |
Options : Common optic options.
114 |
115 |
returns: An opaque optic record.
116 |
117 | Focus on the tail of a list. A list must have at least one element
118 | to have a tail.
119 |
120 | Example:
121 |
122 | > optic:get([optic_lists:tail()], [1,2,3]).
123 | {ok,[2,3]}
124 |
125 |
126 |
127 | Generated by EDoc
128 |
129 |
130 |
--------------------------------------------------------------------------------
/doc/optic_lists.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_lists #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to lists.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 | ## Function Details ##
25 |
26 |
27 |
28 | ### all/0 ###
29 |
30 |
31 | all() -> optic:optic()
32 |
33 |
34 |
35 | __See also:__ [all/1](#all-1).
36 |
37 |
38 |
39 | ### all/1 ###
40 |
41 |
42 | all(Options) -> optic:optic()
43 |
44 |
45 |
46 |
47 | `Options`: Common optic options.
48 |
49 | returns: An opaque optic record.
50 |
51 | Focus on all elements of a list.
52 |
53 | Example:
54 |
55 | ```
56 | > optic:get([optic_lists:all()], [1,2,3]).
57 | {ok,[1,2,3]}
58 | ```
59 |
60 |
61 |
62 | ### head/0 ###
63 |
64 |
65 | head() -> optic:optic()
66 |
67 |
68 |
69 | __See also:__ [head/1](#head-1).
70 |
71 |
72 |
73 | ### head/1 ###
74 |
75 |
76 | head(Options) -> optic:optic()
77 |
78 |
79 |
80 |
81 | `Options`: Common optic options.
82 |
83 | returns: An opaque optic record.
84 |
85 | Focus on the head of a list. The list must have at least one
86 | element to have a head.
87 |
88 | Example:
89 |
90 | ```
91 | > optic:get([optic_lists:head()], [1,2,3]).
92 | {ok,[1]}
93 | ```
94 |
95 |
96 |
97 | ### nth/1 ###
98 |
99 |
100 | nth(N) -> optic:optic()
101 |
102 |
103 |
104 |
105 | __See also:__ [nth/2](#nth-2).
106 |
107 |
108 |
109 | ### nth/2 ###
110 |
111 |
112 | nth(N, Options) -> optic:optic()
113 |
114 |
115 |
116 |
117 | `N`: The index of the list element to focus on. `Options`: Common optic options.
118 |
119 | returns: An opaque optic record.
120 |
121 | Focus on the nth element of a list. As with `lists:nth/2`, indexing
122 | begins at 1.
123 |
124 | Example:
125 |
126 | ```
127 | > optic:get([optic_lists:nth(1)], [1,2,3]).
128 | {ok,[1]}
129 | ```
130 |
131 |
132 |
133 | ### tail/0 ###
134 |
135 |
136 | tail() -> optic:optic()
137 |
138 |
139 |
140 | __See also:__ [tail/1](#tail-1).
141 |
142 |
143 |
144 | ### tail/1 ###
145 |
146 |
147 | tail(Options) -> optic:optic()
148 |
149 |
150 |
151 |
152 | `Options`: Common optic options.
153 |
154 | returns: An opaque optic record.
155 |
156 | Focus on the tail of a list. A list must have at least one element
157 | to have a tail.
158 |
159 | Example:
160 |
161 | ```
162 | > optic:get([optic_lists:tail()], [1,2,3]).
163 | {ok,[2,3]}
164 | ```
165 |
166 |
--------------------------------------------------------------------------------
/doc/optic_maps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_maps
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_maps
13 |
14 | A set of optics specific to maps.
15 |
16 |
17 |
18 | A set of optics specific to maps.
19 |
20 |
38 |
39 |
40 |
41 |
42 |
45 | See also: values/1 .
46 |
47 |
48 |
52 | See also: values/1 .
53 |
54 |
55 |
59 | See also: association/2 .
60 |
61 |
62 |
63 |
association(Key, Options) -> optic:optic()
64 |
65 |
Key : The key to focus on.
66 | Options : Common optic options.
67 |
68 |
returns: An opaque optic record.
69 |
70 | Focus on the association for a map key. An association is the tuple
71 | of a map key and value. If the key is modified, the optic is no
72 | longer well behaved.
73 |
74 | Example:
75 |
76 | > optic:get([optic_maps:association(first)], #{first => 1, second => 2}).
77 | {ok,[{first,1}]}
78 |
79 |
80 |
83 | See also: associations/1 .
84 |
85 |
86 |
87 |
associations(Options) -> optic:optic()
88 |
89 |
Options : Common optic options.
90 |
91 |
returns: An opaque optic record.
92 |
93 | Focus on all associations of a map. An association is a tuple of
94 | the key and value for each entry.
95 |
96 | Example:
97 |
98 | > optic:get([optic_maps:associations()], #{first => 1, second => 2}).
99 | {ok,[{first,1},{second,2}]}
100 |
101 |
102 |
106 | See also: key/2 .
107 |
108 |
109 |
110 |
key(Key, Options) -> optic:optic()
111 |
112 |
Key : The key to focus on.
113 | Options : Common optic options.
114 |
115 |
returns: An opaque optic record.
116 |
117 | Focus on the value of a map key.
118 |
119 | Example:
120 |
121 | > optic:get([optic_maps:key(first)], #{first => 1, second => 2}).
122 | {ok,[1]}
123 |
124 |
125 |
128 | See also: keys/1 .
129 |
130 |
131 |
132 |
keys(Options) -> optic:optic()
133 |
134 |
Options : Common optic options.
135 |
136 |
returns: An opaque optic record.
137 |
138 | Focus on all keys of a map.
139 |
140 | Example:
141 |
142 | > optic:get([optic_maps:keys()], #{first => 1, second => 2}).
143 | {ok,[first,second]}
144 |
145 |
146 |
149 | See also: values/1 .
150 |
151 |
152 |
153 |
values(Options) -> optic:optic()
154 |
155 |
Options : Common optic options.
156 |
157 |
returns: An opaque optic record.
158 |
159 | Focus on all values of a map.
160 |
161 | Example:
162 |
163 | > optic:get([optic_maps:values()], #{first => 1, second => 2}).
164 | {ok,[1,2]}
165 |
166 |
167 |
168 | Generated by EDoc
169 |
170 |
171 |
--------------------------------------------------------------------------------
/doc/optic_maps.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_maps #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to maps.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | ## Function Details ##
26 |
27 |
28 |
29 | ### all/0 ###
30 |
31 |
32 | all() -> optic:optic()
33 |
34 |
35 |
36 | __See also:__ [values/1](#values-1).
37 |
38 |
39 |
40 | ### all/1 ###
41 |
42 |
43 | all(Options) -> optic:optic()
44 |
45 |
46 |
47 |
48 | __See also:__ [values/1](#values-1).
49 |
50 |
51 |
52 | ### association/1 ###
53 |
54 |
55 | association(Key) -> optic:optic()
56 |
57 |
58 |
59 |
60 | __See also:__ [association/2](#association-2).
61 |
62 |
63 |
64 | ### association/2 ###
65 |
66 |
67 | association(Key, Options) -> optic:optic()
68 |
69 |
70 |
71 |
72 | `Key`: The key to focus on. `Options`: Common optic options.
73 |
74 | returns: An opaque optic record.
75 |
76 | Focus on the association for a map key. An association is the tuple
77 | of a map key and value. If the key is modified, the optic is no
78 | longer well behaved.
79 |
80 | Example:
81 |
82 | ```
83 | > optic:get([optic_maps:association(first)], #{first => 1, second => 2}).
84 | {ok,[{first,1}]}
85 | ```
86 |
87 |
88 |
89 | ### associations/0 ###
90 |
91 |
92 | associations() -> optic:optic()
93 |
94 |
95 |
96 | __See also:__ [associations/1](#associations-1).
97 |
98 |
99 |
100 | ### associations/1 ###
101 |
102 |
103 | associations(Options) -> optic:optic()
104 |
105 |
106 |
107 |
108 | `Options`: Common optic options.
109 |
110 | returns: An opaque optic record.
111 |
112 | Focus on all associations of a map. An association is a tuple of
113 | the key and value for each entry.
114 |
115 | Example:
116 |
117 | ```
118 | > optic:get([optic_maps:associations()], #{first => 1, second => 2}).
119 | {ok,[{first,1},{second,2}]}
120 | ```
121 |
122 |
123 |
124 | ### key/1 ###
125 |
126 |
127 | key(Key) -> optic:optic()
128 |
129 |
130 |
131 |
132 | __See also:__ [key/2](#key-2).
133 |
134 |
135 |
136 | ### key/2 ###
137 |
138 |
139 | key(Key, Options) -> optic:optic()
140 |
141 |
142 |
143 |
144 | `Key`: The key to focus on. `Options`: Common optic options.
145 |
146 | returns: An opaque optic record.
147 |
148 | Focus on the value of a map key.
149 |
150 | Example:
151 |
152 | ```
153 | > optic:get([optic_maps:key(first)], #{first => 1, second => 2}).
154 | {ok,[1]}
155 | ```
156 |
157 |
158 |
159 | ### keys/0 ###
160 |
161 |
162 | keys() -> optic:optic()
163 |
164 |
165 |
166 | __See also:__ [keys/1](#keys-1).
167 |
168 |
169 |
170 | ### keys/1 ###
171 |
172 |
173 | keys(Options) -> optic:optic()
174 |
175 |
176 |
177 |
178 | `Options`: Common optic options.
179 |
180 | returns: An opaque optic record.
181 |
182 | Focus on all keys of a map.
183 |
184 | Example:
185 |
186 | ```
187 | > optic:get([optic_maps:keys()], #{first => 1, second => 2}).
188 | {ok,[first,second]}
189 | ```
190 |
191 |
192 |
193 | ### values/0 ###
194 |
195 |
196 | values() -> optic:optic()
197 |
198 |
199 |
200 | __See also:__ [values/1](#values-1).
201 |
202 |
203 |
204 | ### values/1 ###
205 |
206 |
207 | values(Options) -> optic:optic()
208 |
209 |
210 |
211 |
212 | `Options`: Common optic options.
213 |
214 | returns: An opaque optic record.
215 |
216 | Focus on all values of a map.
217 |
218 | Example:
219 |
220 | ```
221 | > optic:get([optic_maps:values()], #{first => 1, second => 2}).
222 | {ok,[1,2]}
223 | ```
224 |
225 |
--------------------------------------------------------------------------------
/doc/optic_orddict.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_orddict #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to orddicts.
9 |
10 |
11 |
12 | ## Description ##
13 | As orddicts are internally represented as a list of pairs, the
14 | type checks used here are not as reliable as those used for other
15 | optics. Please ensure via other means that these optics are only
16 | used with actual orddicts.
17 |
18 | ## Function Index ##
19 |
20 |
21 |
27 |
28 |
29 |
30 |
31 | ## Function Details ##
32 |
33 |
34 |
35 | ### all/0 ###
36 |
37 |
38 | all() -> optic:optic()
39 |
40 |
41 |
42 | __See also:__ [values/1](#values-1).
43 |
44 |
45 |
46 | ### all/1 ###
47 |
48 |
49 | all(Options) -> optic:optic()
50 |
51 |
52 |
53 |
54 | __See also:__ [values/1](#values-1).
55 |
56 |
57 |
58 | ### association/1 ###
59 |
60 |
61 | association(Key) -> optic:optic()
62 |
63 |
64 |
65 |
66 | __See also:__ [association/2](#association-2).
67 |
68 |
69 |
70 | ### association/2 ###
71 |
72 |
73 | association(Key, Options) -> optic:optic()
74 |
75 |
76 |
77 |
78 | `Key`: The key to focus on. `Options`: Common optic options.
79 |
80 | returns: An opaque optic record.
81 |
82 | Focus on the association for an orddict key. An association is the
83 | tuple of a orddict key and value. If the key is modified, the optic is
84 | no longer well behaved.
85 |
86 | Example:
87 |
88 | ```
89 | > optic:get([optic_orddict:association(first)],
90 | orddict:from_list([{first, 1}, {second, 2}])).
91 | {ok,[{first,1}]}
92 | ```
93 |
94 |
95 |
96 | ### associations/0 ###
97 |
98 |
99 | associations() -> optic:optic()
100 |
101 |
102 |
103 | __See also:__ [associations/1](#associations-1).
104 |
105 |
106 |
107 | ### associations/1 ###
108 |
109 |
110 | associations(Options) -> optic:optic()
111 |
112 |
113 |
114 |
115 | `Options`: Common optic options.
116 |
117 | returns: An opaque optic record.
118 |
119 | Focus on all associations of an orddict. An association is a tuple
120 | of the key and value for each entry.
121 |
122 | Example:
123 |
124 | ```
125 | > optic:get([optic_orddict:associations()],
126 | orddict:from_list([{first, 1}, {second, 2}])).
127 | {ok,[{first,1},{second,2}]}
128 | ```
129 |
130 |
131 |
132 | ### key/1 ###
133 |
134 |
135 | key(Key) -> optic:optic()
136 |
137 |
138 |
139 |
140 | __See also:__ [key/2](#key-2).
141 |
142 |
143 |
144 | ### key/2 ###
145 |
146 |
147 | key(Key, Options) -> optic:optic()
148 |
149 |
150 |
151 |
152 | `Key`: The key to focus on. `Options`: Common optic options.
153 |
154 | returns: An opaque optic record.
155 |
156 | Focus on the value of an orddict key.
157 |
158 | Example:
159 |
160 | ```
161 | > optic:get([optic_orddict:key(first)],
162 | orddict:from_list([{first, 1}, {second, 2}])).
163 | {ok,[1]}
164 | ```
165 |
166 |
167 |
168 | ### keys/0 ###
169 |
170 |
171 | keys() -> optic:optic()
172 |
173 |
174 |
175 | __See also:__ [keys/1](#keys-1).
176 |
177 |
178 |
179 | ### keys/1 ###
180 |
181 |
182 | keys(Options) -> optic:optic()
183 |
184 |
185 |
186 |
187 | `Options`: Common optic options.
188 |
189 | returns: An opaque optic record.
190 |
191 | Focus on all keys of an orddict.
192 |
193 | Example:
194 |
195 | ```
196 | > optic:get([optic_orddict:keys()],
197 | orddict:from_list([{first, 1}, {second, 2}])).
198 | {ok,[first,second]}
199 | ```
200 |
201 |
202 |
203 | ### values/0 ###
204 |
205 |
206 | values() -> optic:optic()
207 |
208 |
209 |
210 | __See also:__ [values/1](#values-1).
211 |
212 |
213 |
214 | ### values/1 ###
215 |
216 |
217 | values(Options) -> optic:optic()
218 |
219 |
220 |
221 |
222 | `Options`: Common optic options.
223 |
224 | returns: An opaque optic record.
225 |
226 | Focus on all values of an orddict.
227 |
228 | Example:
229 |
230 | ```
231 | > optic:get([optic_orddict:values()],
232 | orddict:from_list([{first, 1}, {second, 2}])).
233 | {ok,[1,2]}
234 | ```
235 |
236 |
--------------------------------------------------------------------------------
/doc/optic_ordsets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_ordsets
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_ordsets
13 |
14 | A set of optics specific to ordsets.
15 |
16 |
17 |
18 | A set of optics specific to ordsets.
19 |
20 | As ordsets are internally represented as a plain list, the type
21 | checks used here are not as reliable as those used for other
22 | optics. Please ensure via other means that these optics are only
23 | used with actual ordsets.
24 |
25 | all/0
26 | all/1
27 | Focus on all elements of an ordset.
28 |
29 |
30 |
31 |
32 |
33 |
36 | See also: all/1 .
37 |
38 |
39 |
40 |
all(Options) -> optic:optic()
41 |
42 |
Options : Common optic options.
43 |
44 |
returns: An opaque optic record.
45 |
46 | Focus on all elements of an ordset.
47 |
48 | Example:
49 |
50 | > optic:get([optic_ordsets:all()], ordsets:from_list([1,2,3])).
51 | {ok,[1,2,3]}
52 |
53 |
54 |
55 | Generated by EDoc
56 |
57 |
58 |
--------------------------------------------------------------------------------
/doc/optic_ordsets.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_ordsets #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to ordsets.
9 |
10 |
11 |
12 | ## Description ##
13 | As ordsets are internally represented as a plain list, the type
14 | checks used here are not as reliable as those used for other
15 | optics. Please ensure via other means that these optics are only
16 | used with actual ordsets.
17 |
18 | ## Function Index ##
19 |
20 |
21 | all/0 all/1
22 | Focus on all elements of an ordset.
23 |
24 |
25 |
26 |
27 | ## Function Details ##
28 |
29 |
30 |
31 | ### all/0 ###
32 |
33 |
34 | all() -> optic:optic()
35 |
36 |
37 |
38 | __See also:__ [all/1](#all-1).
39 |
40 |
41 |
42 | ### all/1 ###
43 |
44 |
45 | all(Options) -> optic:optic()
46 |
47 |
48 |
49 |
50 | `Options`: Common optic options.
51 |
52 | returns: An opaque optic record.
53 |
54 | Focus on all elements of an ordset.
55 |
56 | Example:
57 |
58 | ```
59 | > optic:get([optic_ordsets:all()], ordsets:from_list([1,2,3])).
60 | {ok,[1,2,3]}
61 | ```
62 |
63 |
--------------------------------------------------------------------------------
/doc/optic_path.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_path
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_path
13 |
14 | Utility functions for constructing optics from lists of selectors.
15 |
16 |
17 |
18 | Utility functions for constructing optics from lists of selectors.
19 |
20 |
21 |
22 | path() = string() | binary() | non_neg_integer() | '*'
23 | A single path component.
24 |
25 |
26 | paths() = [path() ]
27 | A list of path components.
28 |
29 |
30 | new/1
31 | Construct a list of optics from a path.
32 |
33 |
34 |
35 |
36 |
37 |
38 |
new(Paths) -> optic:optics()
39 |
40 |
Paths : A list of path components to convert.
41 |
42 |
returns: A list of opaque optic records.
43 |
44 | Construct a list of optics from a path. The type of the path
45 | component determines the optic used:
46 |
47 |
48 | string: A key for a map-like structure.
49 | binary: A key for a map-like structure.
50 | integer: An index into a list-like structure.
51 | '*': All elements of a list.
52 |
53 |
54 | This heavily depends on the optic_generic
module, see the optics
55 | there for the full list of containers supported.
56 |
57 | Example:
58 |
59 | > optic:get(optic_path(["first"]), ${"first" => 1, "second" => 2}).
60 | {ok,[1]}
61 |
62 |
63 |
64 | Generated by EDoc
65 |
66 |
67 |
--------------------------------------------------------------------------------
/doc/optic_path.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_path #
4 | * [Description](#description)
5 | * [Data Types](#types)
6 | * [Function Index](#index)
7 | * [Function Details](#functions)
8 |
9 | Utility functions for constructing optics from lists of selectors.
10 |
11 |
12 |
13 | ## Data Types ##
14 |
15 |
16 |
17 |
18 | ### path() ###
19 |
20 |
21 |
22 | path() = string() | binary() | non_neg_integer() | *
23 |
24 |
25 | A single path component.
26 |
27 |
28 |
29 | ### paths() ###
30 |
31 |
32 |
33 | paths() = [path() ]
34 |
35 |
36 | A list of path components.
37 |
38 |
39 |
40 | ## Function Index ##
41 |
42 |
43 | new/1
44 | Construct a list of optics from a path.
45 |
46 |
47 |
48 |
49 | ## Function Details ##
50 |
51 |
52 |
53 | ### new/1 ###
54 |
55 |
56 | new(Paths) -> optic:optics()
57 |
58 |
59 |
60 |
61 | `Paths`: A list of path components to convert.
62 |
63 | returns: A list of opaque optic records.
64 |
65 | Construct a list of optics from a path. The type of the path
66 | component determines the optic used:
67 |
68 | * string: A key for a map-like structure.
69 |
70 | * binary: A key for a map-like structure.
71 |
72 | * integer: An index into a list-like structure.
73 |
74 | * '*': All elements of a list.
75 |
76 |
77 | This heavily depends on the `optic_generic` module, see the optics
78 | there for the full list of containers supported.
79 |
80 | Example:
81 |
82 | ```
83 | > optic:get(optic_path(["first"]), ${"first" => 1, "second" => 2}).
84 | {ok,[1]}
85 | ```
86 |
87 |
--------------------------------------------------------------------------------
/doc/optic_proplists.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_proplists
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_proplists
13 |
14 | A set of optics specific to proplists.
15 |
16 |
17 |
18 | A set of optics specific to proplists.
19 |
20 |
38 |
39 |
40 |
41 |
42 |
45 | See also: values/1 .
46 |
47 |
48 |
52 | See also: values/1 .
53 |
54 |
55 |
59 | See also: key/2 .
60 |
61 |
62 |
63 |
key(Key, Options) -> optic:optic()
64 |
65 |
Key : The key to focus on.
66 | Options : Common optic options.
67 |
68 |
returns: An opaque optic record.
69 |
70 | Focus on the value of a property list key. As keys may be
71 | duplicated, this may be multiple values. If the value is not given,
72 | it defaults to the atom true
.
73 |
74 | Example:
75 |
76 | > optic:get([optic_proplists:key(first)], [{first, 1}, {second, 2}]).
77 | {ok,[1]}
78 |
79 |
80 |
83 | See also: keys/1 .
84 |
85 |
86 |
87 |
keys(Options) -> optic:optic()
88 |
89 |
Options : Common optic options.
90 |
91 |
returns: An opaque optic record.
92 |
93 | Focus on all keys of a list of properties. Duplicate keys are
94 | preserved.
95 |
96 | Example:
97 |
98 | > optic:get([optic_proplists:keys()], [{first, 1}, {second, 2}]).
99 | {ok,[first,second]}
100 |
101 |
102 |
105 | See also: properties/1 .
106 |
107 |
108 |
109 |
properties(Options) -> optic:optic()
110 |
111 |
Options : Common optic options.
112 |
113 |
returns: An opaque optic record.
114 |
115 | Focus on all properties of a list of properties. A propety is a
116 | tuple of a key and value. If a value was not given, it defaults to
117 | the atom true
.
118 |
119 | Example:
120 |
121 | > optic:get([optic_proplists:properties()], [{first, 1}, {second, 2}]).
122 | {ok,[{first,1},{second,2}]}
123 |
124 |
125 |
129 | See also: property/2 .
130 |
131 |
132 |
133 |
property(Key, Options) -> optic:optic()
134 |
135 |
Key : The key to focus on.
136 | Options : Common optic options.
137 |
138 |
returns: An opaque optic record.
139 |
140 | Focus on a property in a property list by key. As keys may be
141 | duplicated, this may be multiple properties. If the value is not
142 | given, it defaults to the atom true
. If the key is modified, the
143 | optic is no longer well behaved.
144 |
145 | Example:
146 |
147 | > optic:get([optic_proplists:property(first)], [{first, 1}, {second, 2}]).
148 | {ok,[{first,1}]}
149 |
150 |
151 |
154 | See also: values/1 .
155 |
156 |
157 |
158 |
values(Options) -> optic:optic()
159 |
160 |
Options : Common optic options.
161 |
162 |
returns: An opaque optic record.
163 |
164 | Focus on all values of a list of properties.
165 |
166 | Example:
167 |
168 | > optic:get([optic_proplists:values()], [{first, 1}, {second, 2}]).
169 | {ok,[1,2]}
170 |
171 |
172 |
173 | Generated by EDoc
174 |
175 |
176 |
--------------------------------------------------------------------------------
/doc/optic_proplists.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_proplists #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to proplists.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | ## Function Details ##
26 |
27 |
28 |
29 | ### all/0 ###
30 |
31 |
32 | all() -> optic:optic()
33 |
34 |
35 |
36 | __See also:__ [values/1](#values-1).
37 |
38 |
39 |
40 | ### all/1 ###
41 |
42 |
43 | all(Options) -> optic:optic()
44 |
45 |
46 |
47 |
48 | __See also:__ [values/1](#values-1).
49 |
50 |
51 |
52 | ### key/1 ###
53 |
54 |
55 | key(Key) -> optic:optic()
56 |
57 |
58 |
59 |
60 | __See also:__ [key/2](#key-2).
61 |
62 |
63 |
64 | ### key/2 ###
65 |
66 |
67 | key(Key, Options) -> optic:optic()
68 |
69 |
70 |
71 |
72 | `Key`: The key to focus on. `Options`: Common optic options.
73 |
74 | returns: An opaque optic record.
75 |
76 | Focus on the value of a property list key. As keys may be
77 | duplicated, this may be multiple values. If the value is not given,
78 | it defaults to the atom `true`.
79 |
80 | Example:
81 |
82 | ```
83 | > optic:get([optic_proplists:key(first)], [{first, 1}, {second, 2}]).
84 | {ok,[1]}
85 | ```
86 |
87 |
88 |
89 | ### keys/0 ###
90 |
91 |
92 | keys() -> optic:optic()
93 |
94 |
95 |
96 | __See also:__ [keys/1](#keys-1).
97 |
98 |
99 |
100 | ### keys/1 ###
101 |
102 |
103 | keys(Options) -> optic:optic()
104 |
105 |
106 |
107 |
108 | `Options`: Common optic options.
109 |
110 | returns: An opaque optic record.
111 |
112 | Focus on all keys of a list of properties. Duplicate keys are
113 | preserved.
114 |
115 | Example:
116 |
117 | ```
118 | > optic:get([optic_proplists:keys()], [{first, 1}, {second, 2}]).
119 | {ok,[first,second]}
120 | ```
121 |
122 |
123 |
124 | ### properties/0 ###
125 |
126 |
127 | properties() -> optic:optic()
128 |
129 |
130 |
131 | __See also:__ [properties/1](#properties-1).
132 |
133 |
134 |
135 | ### properties/1 ###
136 |
137 |
138 | properties(Options) -> optic:optic()
139 |
140 |
141 |
142 |
143 | `Options`: Common optic options.
144 |
145 | returns: An opaque optic record.
146 |
147 | Focus on all properties of a list of properties. A propety is a
148 | tuple of a key and value. If a value was not given, it defaults to
149 | the atom `true`.
150 |
151 | Example:
152 |
153 | ```
154 | > optic:get([optic_proplists:properties()], [{first, 1}, {second, 2}]).
155 | {ok,[{first,1},{second,2}]}
156 | ```
157 |
158 |
159 |
160 | ### property/1 ###
161 |
162 |
163 | property(Key) -> optic:optic()
164 |
165 |
166 |
167 |
168 | __See also:__ [property/2](#property-2).
169 |
170 |
171 |
172 | ### property/2 ###
173 |
174 |
175 | property(Key, Options) -> optic:optic()
176 |
177 |
178 |
179 |
180 | `Key`: The key to focus on. `Options`: Common optic options.
181 |
182 | returns: An opaque optic record.
183 |
184 | Focus on a property in a property list by key. As keys may be
185 | duplicated, this may be multiple properties. If the value is not
186 | given, it defaults to the atom `true`. If the key is modified, the
187 | optic is no longer well behaved.
188 |
189 | Example:
190 |
191 | ```
192 | > optic:get([optic_proplists:property(first)], [{first, 1}, {second, 2}]).
193 | {ok,[{first,1}]}
194 | ```
195 |
196 |
197 |
198 | ### values/0 ###
199 |
200 |
201 | values() -> optic:optic()
202 |
203 |
204 |
205 | __See also:__ [values/1](#values-1).
206 |
207 |
208 |
209 | ### values/1 ###
210 |
211 |
212 | values(Options) -> optic:optic()
213 |
214 |
215 |
216 |
217 | `Options`: Common optic options.
218 |
219 | returns: An opaque optic record.
220 |
221 | Focus on all values of a list of properties.
222 |
223 | Example:
224 |
225 | ```
226 | > optic:get([optic_proplists:values()], [{first, 1}, {second, 2}]).
227 | {ok,[1,2]}
228 | ```
229 |
230 |
--------------------------------------------------------------------------------
/doc/optic_sets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_sets
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_sets
13 |
14 | A set of optics specific to sets.
15 |
16 |
17 |
18 | A set of optics specific to sets.
19 |
20 | all/0
21 | all/1
22 | Focus on all elements of a set.
23 |
24 |
25 |
26 |
27 |
28 |
31 | See also: all/1 .
32 |
33 |
34 |
35 |
all(Options) -> optic:optic()
36 |
37 |
Options : Common optic options.
38 |
39 |
returns: An opaque optic record.
40 |
41 | Focus on all elements of a set.
42 |
43 | Example:
44 |
45 | > optic:get([optic_sets:all()], sets:from_list([1,2,3])).
46 | {ok,[1,2,3]}
47 |
48 |
49 |
50 | Generated by EDoc
51 |
52 |
53 |
--------------------------------------------------------------------------------
/doc/optic_sets.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_sets #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to sets.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 | ## Function Details ##
22 |
23 |
24 |
25 | ### all/0 ###
26 |
27 |
28 | all() -> optic:optic()
29 |
30 |
31 |
32 | __See also:__ [all/1](#all-1).
33 |
34 |
35 |
36 | ### all/1 ###
37 |
38 |
39 | all(Options) -> optic:optic()
40 |
41 |
42 |
43 |
44 | `Options`: Common optic options.
45 |
46 | returns: An opaque optic record.
47 |
48 | Focus on all elements of a set.
49 |
50 | Example:
51 |
52 | ```
53 | > optic:get([optic_sets:all()], sets:from_list([1,2,3])).
54 | {ok,[1,2,3]}
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/doc/optic_tuples.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Module optic_tuples
6 |
7 |
8 |
9 |
10 |
11 |
12 | Module optic_tuples
13 |
14 | A set of optics specific to tuples.
15 |
16 |
17 |
18 | A set of optics specific to tuples.
19 |
20 |
30 |
31 |
32 |
33 |
34 |
37 | See also: all/1 .
38 |
39 |
40 |
41 |
all(Options) -> optic:optic()
42 |
43 |
Options : Common optic options.
44 |
45 |
returns: An opaque optic record.
46 |
47 | Focus on all elements of a tuple.
48 |
49 | Example:
50 |
51 | > optic:get([optic_tuples:all()], {1,2,3}).
52 | {ok,[1,2,3]}
53 |
54 |
55 |
59 | See also: element/2 .
60 |
61 |
62 |
63 |
element(N, Options) -> optic:optic()
64 |
65 |
N : The index of the tuple element to focus on.
66 | Options : Common optic options.
67 |
68 |
returns: An opaque optic record.
69 |
70 | Focus on the nth element of a tuple. As with erlang:element/2
,
71 | indexing begins at 1.
72 |
73 | Example:
74 |
75 | > optic:get([optic_tuples:element(1)], {1,2,3}).
76 | {ok,[1]}
77 |
78 |
79 |
80 |
field(Tag, Size, N) -> optic:optic()
81 |
Tag = atom() Size = pos_integer() N = pos_integer()
82 |
83 | See also: field/4 .
84 |
85 |
86 |
87 |
field(Tag, Size, N, Options) -> optic:optic()
88 |
89 |
Tag : The expected record tag.
90 | Size : The expected record size.
91 | N : The index of the field in the record tuple.
92 | Options : Common optic options.
93 |
94 |
returns: An opaque optic record.
95 |
96 | Focus on a record field. As records are a compiler construct, this
97 | depends on the ?OPTIC_FIELD
macro in include/optic_tuples.hrl
98 | to construct the required arguments from the record definition.
99 |
100 | Given the record definition:
101 |
102 | -include_lib("optic/include/optic_tuples.hrl").
103 | -record(example, {first}).
104 |
105 | Example:
106 |
107 | > optic:get([optic_tuples:field(?OPTIC_FIELD(example, first))],
108 | #example{first=1}).
109 | {ok,[1]}
110 |
111 |
112 |
113 | Generated by EDoc
114 |
115 |
116 |
--------------------------------------------------------------------------------
/doc/optic_tuples.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Module optic_tuples #
4 | * [Description](#description)
5 | * [Function Index](#index)
6 | * [Function Details](#functions)
7 |
8 | A set of optics specific to tuples.
9 |
10 |
11 |
12 | ## Function Index ##
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 | ## Function Details ##
24 |
25 |
26 |
27 | ### all/0 ###
28 |
29 |
30 | all() -> optic:optic()
31 |
32 |
33 |
34 | __See also:__ [all/1](#all-1).
35 |
36 |
37 |
38 | ### all/1 ###
39 |
40 |
41 | all(Options) -> optic:optic()
42 |
43 |
44 |
45 |
46 | `Options`: Common optic options.
47 |
48 | returns: An opaque optic record.
49 |
50 | Focus on all elements of a tuple.
51 |
52 | Example:
53 |
54 | ```
55 | > optic:get([optic_tuples:all()], {1,2,3}).
56 | {ok,[1,2,3]}
57 | ```
58 |
59 |
60 |
61 | ### element/1 ###
62 |
63 |
64 | element(N) -> optic:optic()
65 |
66 |
67 |
68 |
69 | __See also:__ [element/2](#element-2).
70 |
71 |
72 |
73 | ### element/2 ###
74 |
75 |
76 | element(N, Options) -> optic:optic()
77 |
78 |
79 |
80 |
81 | `N`: The index of the tuple element to focus on. `Options`: Common optic options.
82 |
83 | returns: An opaque optic record.
84 |
85 | Focus on the nth element of a tuple. As with `erlang:element/2`,
86 | indexing begins at 1.
87 |
88 | Example:
89 |
90 | ```
91 | > optic:get([optic_tuples:element(1)], {1,2,3}).
92 | {ok,[1]}
93 | ```
94 |
95 |
96 |
97 | ### field/3 ###
98 |
99 |
100 | field(Tag, Size, N) -> optic:optic()
101 |
102 |
103 | Tag = atom()
Size = pos_integer()
N = pos_integer()
104 |
105 | __See also:__ [field/4](#field-4).
106 |
107 |
108 |
109 | ### field/4 ###
110 |
111 |
112 | field(Tag, Size, N, Options) -> optic:optic()
113 |
114 |
115 |
116 |
117 | `Tag`: The expected record tag. `Size`: The expected record size. `N`: The index of the field in the record tuple. `Options`: Common optic options.
118 |
119 | returns: An opaque optic record.
120 |
121 | Focus on a record field. As records are a compiler construct, this
122 | depends on the `?OPTIC_FIELD` macro in `include/optic_tuples.hrl`
123 | to construct the required arguments from the record definition.
124 |
125 | Given the record definition:
126 |
127 | ```
128 | -include_lib("optic/include/optic_tuples.hrl").
129 | -record(example, {first}).
130 | ```
131 |
132 | Example:
133 |
134 | ```
135 | > optic:get([optic_tuples:field(?OPTIC_FIELD(example, first))],
136 | #example{first=1}).
137 | {ok,[1]}
138 | ```
139 |
140 |
--------------------------------------------------------------------------------
/doc/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* standard EDoc style sheet */
2 | body {
3 | font-family: Verdana, Arial, Helvetica, sans-serif;
4 | margin-left: .25in;
5 | margin-right: .2in;
6 | margin-top: 0.2in;
7 | margin-bottom: 0.2in;
8 | color: #000000;
9 | background-color: #ffffff;
10 | }
11 | h1,h2 {
12 | margin-left: -0.2in;
13 | }
14 | div.navbar {
15 | background-color: #add8e6;
16 | padding: 0.2em;
17 | }
18 | h2.indextitle {
19 | padding: 0.4em;
20 | background-color: #add8e6;
21 | }
22 | h3.function,h3.typedecl {
23 | background-color: #add8e6;
24 | padding-left: 1em;
25 | }
26 | div.spec {
27 | margin-left: 2em;
28 | background-color: #eeeeee;
29 | }
30 | a.module {
31 | text-decoration:none
32 | }
33 | a.module:hover {
34 | background-color: #eeeeee;
35 | }
36 | ul.definitions {
37 | list-style-type: none;
38 | }
39 | ul.index {
40 | list-style-type: none;
41 | background-color: #eeeeee;
42 | }
43 |
44 | /*
45 | * Minor style tweaks
46 | */
47 | ul {
48 | list-style-type: square;
49 | }
50 | table {
51 | border-collapse: collapse;
52 | }
53 | td {
54 | padding: 3
55 | }
56 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: "3"
3 |
4 | services:
5 |
6 | test:
7 | build:
8 | context: .
9 | container_name: partial
10 | command: test-unit
11 |
--------------------------------------------------------------------------------
/include/optic_tuples.hrl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Macros for the optic_tuples module.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 |
7 | % This macro creates the first three parameters required by
8 | % optic_tuple:field/3 for selecting the field of a record. It requires
9 | % the record to be defined in the current module.
10 | -define(OPTIC_FIELD(Record, Field), (Record), record_info(size, (Record)), (#Record.Field)).
11 |
--------------------------------------------------------------------------------
/rebar.config:
--------------------------------------------------------------------------------
1 | {minimum_otp_vsn, "18.0"}.
2 |
3 | {erl_opts, [debug_info,
4 | {warn_format, 1},
5 | warn_export_all,
6 | warn_export_vars,
7 | warn_obsolete_guard,
8 | warn_unused_import]
9 | }.
10 |
11 | {plugins, [rebar3_hex]}.
12 |
13 | {dialyzer, [{plt_prefix, "optic"},
14 | {warnings, [unmatched_returns,
15 | error_handling,
16 | race_conditions,
17 | underspecs]}]
18 | }.
19 |
20 | {xref_warnings, true}.
21 |
22 | {profiles, [{native, [{erl_opts, [{native, o3},
23 | {d, 'NATIVE'}]}]
24 | },
25 | {test, [{erl_opts, [{d, 'TEST'}]},
26 | {deps, [proper]},
27 | {plugins, [geas_rebar3,
28 | rebar3_lint,
29 | rebar3_proper]},
30 | {dialyzer, [{plt_prefix, "optic_test"}]}]
31 | },
32 | {markdown, [{deps, [edown]},
33 | {edoc_opts, [{preprocess, true},
34 | {doclet, edown_doclet},
35 | {top_level_readme, {"./README.md",
36 | "http://github.com/jkrukoff/optic"}}]}]
37 | }]
38 | }.
39 |
--------------------------------------------------------------------------------
/rebar.lock:
--------------------------------------------------------------------------------
1 | [].
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | docker-compose
2 | html2text
3 | yamllint
4 |
--------------------------------------------------------------------------------
/src/optic.app.src:
--------------------------------------------------------------------------------
1 | {application, optic,
2 | [{pkg_name, "optic"},
3 | {description, "A library for reading and updating deeply nested data."},
4 | {vsn, "3.1.0"},
5 | {applications, [kernel,
6 | stdlib]},
7 | {modules, [optic]},
8 | {registered, []},
9 | {env, []},
10 | {licenses, ["Apache 2.0"]},
11 | {links, [{"GitHub", "https://github.com/jkrukoff/optic"}]},
12 | {extra, [{maintainers, ["John Krukoff"]}]}]}.
13 |
--------------------------------------------------------------------------------
/src/optic_array.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to arrays.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_array).
7 |
8 | %% API
9 | -export([all/0,
10 | all/1,
11 | nth/1,
12 | nth/2]).
13 |
14 | %%%===================================================================
15 | %%% API
16 | %%%===================================================================
17 |
18 | %% @see all/1
19 | -spec all() -> optic:optic().
20 | all() ->
21 | all(#{}).
22 |
23 | %% @doc
24 | %% Focus on all values of an array.
25 | %%
26 | %% Example:
27 | %%
28 | %% ```
29 | %% > optic:get([optic_array:all()], array:from_list([1,2,3])).
30 | %% {ok,[1,2,3]}
31 | %% '''
32 | %% @end
33 | %% @param Options Common optic options.
34 | %% @returns An opaque optic record.
35 | -spec all(Options) -> optic:optic() when
36 | Options :: optic:variations().
37 | all(Options) ->
38 | Fold =
39 | fun (Fun, Acc, Array) ->
40 | case is_array(Array) of
41 | true ->
42 | {ok, array:foldl(fun (_Index, Elem, InnerAcc) ->
43 | Fun(Elem, InnerAcc)
44 | end, Acc, Array)};
45 | false ->
46 | {error, undefined}
47 | end
48 | end,
49 | MapFold =
50 | fun (Fun, Acc, Array) ->
51 | case is_array(Array) of
52 | true ->
53 | {ok, array:foldl(fun (Index, Elem, {InnerArray, InnerAcc}) ->
54 | {NewElem, NewAcc} = Fun(Elem, InnerAcc),
55 | {array:set(Index, NewElem, InnerArray), NewAcc}
56 | end,
57 | {Array, Acc},
58 | Array)};
59 | false ->
60 | {error, undefined}
61 | end
62 | end,
63 | New =
64 | fun (_Data, Template) ->
65 | array:new([{default, Template}])
66 | end,
67 | Optic = optic:new(MapFold, Fold),
68 | optic:variations(Optic, Options, New).
69 |
70 | %% @see nth/2
71 | -spec nth(N) -> optic:optic() when
72 | N :: pos_integer().
73 | nth(N) ->
74 | nth(N, #{}).
75 |
76 | %% @doc
77 | %% Focus on the nth value of an array. Like lists, but unlike the
78 | %% standard array operations, indexing begins at 1.
79 | %%
80 | %% Example:
81 | %%
82 | %% ```
83 | %% > optic:get([optic_array:nth(1)], array:from_list([1,2,3])).
84 | %% {ok,[1]}
85 | %% '''
86 | %% @end
87 | %% @param N The index of the array value to focus on.
88 | %% @param Options Common optic options.
89 | %% @returns An opaque optic record.
90 | -spec nth(N, Options) -> optic:optic() when
91 | N :: pos_integer(),
92 | Options :: optic:variations().
93 | nth(N, Options) when N >= 1 ->
94 | Index = N - 1,
95 | Fold =
96 | fun (Fun, Acc, Array) ->
97 | case is_array(Array) andalso valid_index(Index, Array) of
98 | true ->
99 | Elem = array:get(Index, Array),
100 | {ok, Fun(Elem, Acc)};
101 | false ->
102 | {error, undefined}
103 | end
104 | end,
105 | MapFold =
106 | fun (Fun, Acc, Array) ->
107 | case is_array(Array) andalso valid_index(Index, Array) of
108 | true ->
109 | Elem = array:get(Index, Array),
110 | {NewElem, NewAcc} = Fun(Elem, Acc),
111 | {ok, {array:set(Index, NewElem, Array), NewAcc}};
112 | false ->
113 | {error, undefined}
114 | end
115 | end,
116 | New =
117 | fun (Data, Template) ->
118 | case is_array(Data) of
119 | true ->
120 | array:resize(N, Data);
121 | false ->
122 | array:new(N, [{default, Template}])
123 | end
124 | end,
125 | Optic = optic:new(MapFold, Fold),
126 | optic:variations(Optic, Options, New).
127 |
128 | %%%===================================================================
129 | %%% Internal Functions
130 | %%%===================================================================
131 |
132 | is_array(Unknown) ->
133 | try array:size(Unknown) of
134 | _ ->
135 | true
136 | catch
137 | error:badarg ->
138 | false
139 | end.
140 |
141 | valid_index(Index, Array) when Index >= 0 ->
142 | case array:is_fix(Array) of
143 | true ->
144 | Index < array:size(Array);
145 | false ->
146 | true
147 | end.
148 |
--------------------------------------------------------------------------------
/src/optic_gb_sets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to gb_sets.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_gb_sets).
7 |
8 | %% API
9 | -export([all/0,
10 | all/1]).
11 |
12 | %%%===================================================================
13 | %%% API
14 | %%%===================================================================
15 |
16 | %% @see all/1
17 | -spec all() -> optic:optic().
18 | all() ->
19 | all(#{}).
20 |
21 | %% @doc
22 | %% Focus on all elements of a gb_set.
23 | %%
24 | %% Example:
25 | %%
26 | %% ```
27 | %% > optic:get([optic_gb_sets:all()], gb_sets:from_list([1,2,3])).
28 | %% {ok,[1,2,3]}
29 | %% '''
30 | %% @end
31 | %% @param Options Common optic options.
32 | %% @returns An opaque optic record.
33 | -spec all(Options) -> optic:optic() when
34 | Options :: optic:variations().
35 | all(Options) ->
36 | Fold =
37 | fun (Fun, Acc, Set) ->
38 | case is_gb_set(Set) of
39 | true ->
40 | {ok, gb_sets:fold(Fun, Acc, Set)};
41 | false ->
42 | {error, undefined}
43 | end
44 | end,
45 | MapFold =
46 | fun (Fun, Acc, Set) ->
47 | case is_gb_set(Set) of
48 | true ->
49 | {ok, gb_sets:fold(fun (Elem, {InnerSet, InnerAcc}) ->
50 | {NewElem, NewAcc} = Fun(Elem, InnerAcc),
51 | {gb_sets:add_element(NewElem, InnerSet), NewAcc}
52 | end,
53 | {gb_sets:new(), Acc},
54 | Set)};
55 | false ->
56 | {error, undefined}
57 | end
58 | end,
59 | New =
60 | fun (_Data, _Template) ->
61 | gb_sets:new()
62 | end,
63 | Optic = optic:new(MapFold, Fold),
64 | optic:variations(Optic, Options, New).
65 |
66 | %%%===================================================================
67 | %%% Internal Functions
68 | %%%===================================================================
69 |
70 | is_gb_set(Unknown) ->
71 | try gb_sets:size(Unknown) of
72 | _ ->
73 | true
74 | catch
75 | error:function_clause ->
76 | false
77 | end.
78 |
--------------------------------------------------------------------------------
/src/optic_generic.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of generic optics that can be applied to multiple container
4 | %%% types.
5 | %%%
6 | %%% Intended both as a convenience and to support optic creation from
7 | %%% parsed paths in optic_path.
8 | %%%
9 | %%% Because of the ambiguous types they support, these optics do not
10 | %%% support the standard optic options. Instead, they always skip
11 | %%% unexpected types and never create missing values.
12 | %%% @end
13 | %%%-------------------------------------------------------------------
14 | -module(optic_generic).
15 |
16 | %% API
17 | -export([key/1,
18 | index/1]).
19 |
20 | %%%===================================================================
21 | %%% API
22 | %%%===================================================================
23 |
24 | %% @doc
25 | %% Focus on the value of many different key/value like mappings.
26 | %% Understands how to focus on maps, property lists, dicts, orddicts
27 | %% and gb_trees. Does not support the usual optic options.
28 | %%
29 | %% Example:
30 | %%
31 | %% ```
32 | %% > optic:get([optic_generic:key(first)], #{first => 1}).
33 | %% {ok,[1]}
34 | %% '''
35 | %% @end
36 | %% @param Key The key to focus on.
37 | %% @returns An opaque optic record.
38 | -spec key(Key) -> optic:optic() when
39 | Key :: term().
40 | key(Key) ->
41 | Fold =
42 | fun (Fun, Acc, Map) when is_map(Map) ->
43 | case Map of
44 | #{Key:=Value} ->
45 | {ok, Fun(Value, Acc)};
46 | _ ->
47 | {ok, Acc}
48 | end;
49 | (Fun, Acc, List) when is_list(List) ->
50 | % This might be a proplist or an orddict.
51 | Values = proplists:get_all_values(Key, List),
52 | {ok, lists:foldl(Fun, Acc, Values)};
53 | (Fun, Acc, Unknown) ->
54 | case {is_dict(Unknown), is_gb_tree(Unknown)} of
55 | {true, _} ->
56 | % It's bad if is_dict & is_gb_tree ever both return
57 | % true, but I can't justify throwing an error when
58 | % this is already doing such fuzzy guessing of types.
59 | Dict = Unknown,
60 | case dict:find(Key, Dict) of
61 | {ok, Value} ->
62 | {ok, Fun(Value, Acc)};
63 | error ->
64 | {ok, Acc}
65 | end;
66 | {false, true} ->
67 | Tree = Unknown,
68 | case gb_trees:lookup(Key, Tree) of
69 | {value, Value} ->
70 | {ok, Fun(Value, Acc)};
71 | none ->
72 | {ok, Acc}
73 | end;
74 | {false, false} ->
75 | {ok, Acc}
76 | end
77 | end,
78 | MapFold =
79 | fun (Fun, Acc, Map) when is_map(Map) ->
80 | case Map of
81 | #{Key:=Value} ->
82 | {NewValue, NewAcc} = Fun(Value, Acc),
83 | {ok, {Map#{Key:=NewValue}, NewAcc}};
84 | _ ->
85 | {ok, {Map, Acc}}
86 | end;
87 | (Fun, Acc, List) when is_list(List) ->
88 | % This might be a proplist or an orddict.
89 | {ok, lists:mapfoldl(fun (Elem, InnerAcc) ->
90 | case proplists:is_defined(Key, [Elem]) of
91 | true ->
92 | Value = proplists:get_value(Key, [Elem]),
93 | {NewValue, NewAcc} = Fun(Value, InnerAcc),
94 | {{Key, NewValue}, NewAcc};
95 | false ->
96 | {Elem, InnerAcc}
97 | end
98 | end,
99 | Acc,
100 | List)};
101 | (Fun, Acc, Unknown) ->
102 | case {is_dict(Unknown), is_gb_tree(Unknown)} of
103 | {true, _} ->
104 | % It's bad if is_dict & is_gb_tree ever both return
105 | % true, but I can't justify throwing an error when
106 | % this is already doing such fuzzy guessing of types.
107 | Dict = Unknown,
108 | case dict:find(Key, Dict) of
109 | {ok, Value} ->
110 | {NewValue, NewAcc} = Fun(Value, Acc),
111 | {ok, {dict:store(Key, NewValue, Dict), NewAcc}};
112 | error ->
113 | {ok, {Dict, Acc}}
114 | end;
115 | {false, true} ->
116 | Tree = Unknown,
117 | case gb_trees:lookup(Key, Tree) of
118 | {value, Value} ->
119 | {NewValue, NewAcc} = Fun(Value, Acc),
120 | {ok, {gb_trees:update(Key, NewValue, Tree), NewAcc}};
121 | none ->
122 | {ok, {Tree, Acc}}
123 | end;
124 | {false, false} ->
125 | {ok, {Unknown, Acc}}
126 | end
127 | end,
128 | optic:new(MapFold, Fold).
129 |
130 | %% @doc
131 | %% Focus on an element of a list like container. Indexing begins at 1.
132 | %% Understands how to focus on lists and tuples. Does not support the
133 | %% usual optic options.
134 | %%
135 | %% Example:
136 | %%
137 | %% ```
138 | %% > optic:get([optic_generic:index(3)], [1, 2, 3]).
139 | %% {ok,[3]}
140 | %% '''
141 | %% @end
142 | %% @param Index The one based index of the element to focus on.
143 | %% @returns An opaque optic record.
144 | -spec index(Index) -> optic:optic() when
145 | Index :: non_neg_integer().
146 | index(Index) ->
147 | Fold =
148 | fun (Fun, Acc, List) when Index =< length(List) ->
149 | Elem = lists:nth(Index, List),
150 | {ok, Fun(Elem, Acc)};
151 | (Fun, Acc, Tuple) when Index =< tuple_size(Tuple) ->
152 | Elem = erlang:element(Index, Tuple),
153 | {ok, Fun(Elem, Acc)};
154 | (_Fun, Acc, _Data) ->
155 | {ok, Acc}
156 | end,
157 | MapFold =
158 | fun (Fun, Acc, List) when Index =< length(List) ->
159 | {Before, [Head | Tail]} = lists:split(Index - 1, List),
160 | {NewHead, NewAcc} = Fun(Head, Acc),
161 | {ok, {Before ++ [NewHead] ++ Tail, NewAcc}};
162 | (Fun, Acc, Tuple) when Index =< tuple_size(Tuple) ->
163 | Elem = erlang:element(Index, Tuple),
164 | {NewElem, NewAcc} = Fun(Elem, Acc),
165 | {ok, {erlang:setelement(Index, Tuple, NewElem), NewAcc}};
166 | (_Fun, Acc, Unknown) ->
167 | {ok, {Unknown, Acc}}
168 | end,
169 | optic:new(MapFold, Fold).
170 |
171 | %%%===================================================================
172 | %%% Internal Functions
173 | %%%===================================================================
174 |
175 | is_dict(Unknown) ->
176 | try dict:size(Unknown) of
177 | _ ->
178 | true
179 | catch
180 | error:function_clause ->
181 | false
182 | end.
183 |
184 | is_gb_tree(Unknown) ->
185 | try gb_trees:size(Unknown) of
186 | _ ->
187 | true
188 | catch
189 | error:function_clause ->
190 | false
191 | end.
192 |
--------------------------------------------------------------------------------
/src/optic_lists.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to lists.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_lists).
7 |
8 | %% API
9 | -export([all/0,
10 | all/1,
11 | head/0,
12 | head/1,
13 | tail/0,
14 | tail/1,
15 | nth/1,
16 | nth/2]).
17 |
18 | %%%===================================================================
19 | %%% API
20 | %%%===================================================================
21 |
22 | %% @see all/1
23 | -spec all() -> optic:optic().
24 | all() ->
25 | all(#{}).
26 |
27 | %% @doc
28 | %% Focus on all elements of a list.
29 | %%
30 | %% Example:
31 | %%
32 | %% ```
33 | %% > optic:get([optic_lists:all()], [1,2,3]).
34 | %% {ok,[1,2,3]}
35 | %% '''
36 | %% @end
37 | %% @param Options Common optic options.
38 | %% @returns An opaque optic record.
39 | -spec all(Options) -> optic:optic() when
40 | Options :: optic:variations().
41 | all(Options) ->
42 | Fold =
43 | fun (Fun, Acc, List) when is_list(List) ->
44 | {ok, lists:foldl(Fun, Acc, List)};
45 | (_, _, _) ->
46 | {error, undefined}
47 | end,
48 | MapFold =
49 | fun (Fun, Acc, List) when is_list(List) ->
50 | {ok, lists:mapfoldl(Fun, Acc, List)};
51 | (_, _, _) ->
52 | {error, undefined}
53 | end,
54 | New =
55 | fun (_Data, _Template) ->
56 | []
57 | end,
58 | Optic = optic:new(MapFold, Fold),
59 | optic:variations(Optic, Options, New).
60 |
61 | %% @see head/1
62 | -spec head() -> optic:optic().
63 | head() ->
64 | head(#{}).
65 |
66 | %% @doc
67 | %% Focus on the head of a list. The list must have at least one
68 | %% element to have a head.
69 | %%
70 | %% Example:
71 | %%
72 | %% ```
73 | %% > optic:get([optic_lists:head()], [1,2,3]).
74 | %% {ok,[1]}
75 | %% '''
76 | %% @end
77 | %% @param Options Common optic options.
78 | %% @returns An opaque optic record.
79 | -spec head(Options) -> optic:optic() when
80 | Options :: optic:variations().
81 | head(Options) ->
82 | Fold =
83 | fun (Fun, Acc, [Head | _]) ->
84 | {ok, Fun(Head, Acc)};
85 | (_, _, _) ->
86 | {error, undefined}
87 | end,
88 | MapFold =
89 | fun (Fun, Acc, [Head | Tail]) ->
90 | {NewHead, NewAcc} = Fun(Head, Acc),
91 | {ok, {[NewHead | Tail], NewAcc}};
92 | (_, _, _) ->
93 | {error, undefined}
94 | end,
95 | New =
96 | fun (_Data, Template) ->
97 | [Template]
98 | end,
99 | Optic = optic:new(MapFold, Fold),
100 | optic:variations(Optic, Options, New).
101 |
102 | %% @see tail/1
103 | -spec tail() -> optic:optic().
104 | tail() ->
105 | tail(#{}).
106 |
107 | %% @doc
108 | %% Focus on the tail of a list. A list must have at least one element
109 | %% to have a tail.
110 | %%
111 | %% Example:
112 | %%
113 | %% ```
114 | %% > optic:get([optic_lists:tail()], [1,2,3]).
115 | %% {ok,[2,3]}
116 | %% '''
117 | %% @end
118 | %% @param Options Common optic options.
119 | %% @returns An opaque optic record.
120 | -spec tail(Options) -> optic:optic() when
121 | Options :: optic:variations().
122 | tail(Options) ->
123 | Fold =
124 | fun (Fun, Acc, [_ | Tail]) ->
125 | {ok, lists:foldl(Fun, Acc, Tail)};
126 | (_, _, _) ->
127 | {error, undefined}
128 | end,
129 | MapFold =
130 | fun (Fun, Acc, [Head | Tail]) ->
131 | {NewTail, NewAcc} = lists:mapfoldl(Fun, Acc, Tail),
132 | {ok, {[Head | NewTail], NewAcc}};
133 | (_, _, _) ->
134 | {error, undefined}
135 | end,
136 | New =
137 | fun (_Data, Template) ->
138 | [Template]
139 | end,
140 | Optic = optic:new(MapFold, Fold),
141 | optic:variations(Optic, Options, New).
142 |
143 | %% @see nth/2
144 | -spec nth(N) -> optic:optic() when
145 | N :: pos_integer().
146 | nth(N) ->
147 | nth(N, #{}).
148 |
149 | %% @doc
150 | %% Focus on the nth element of a list. As with `lists:nth/2', indexing
151 | %% begins at 1.
152 | %%
153 | %% Example:
154 | %%
155 | %% ```
156 | %% > optic:get([optic_lists:nth(1)], [1,2,3]).
157 | %% {ok,[1]}
158 | %% '''
159 | %% @end
160 | %% @param N The index of the list element to focus on.
161 | %% @param Options Common optic options.
162 | %% @returns An opaque optic record.
163 | -spec nth(N, Options) -> optic:optic() when
164 | N :: pos_integer(),
165 | Options :: optic:variations().
166 | nth(N, Options) ->
167 | Fold =
168 | fun (Fun, Acc, List) when N =< length(List) ->
169 | Nth = lists:nth(N, List),
170 | {ok, Fun(Nth, Acc)};
171 | (_, _, _) ->
172 | {error, undefined}
173 | end,
174 | MapFold =
175 | fun (Fun, Acc, List) when N =< length(List) ->
176 | {Before, [Head | Tail]} = lists:split(N - 1, List),
177 | {NewHead, NewAcc} = Fun(Head, Acc),
178 | {ok, {Before ++ [NewHead] ++ Tail, NewAcc}};
179 | (_, _, _) ->
180 | {error, undefined}
181 | end,
182 | New =
183 | fun (Data, Template) when is_list(Data) ->
184 | Data ++ lists:duplicate(N - length(Data), Template);
185 | (_Data, Template) ->
186 | lists:duplicate(N, Template)
187 | end,
188 | Optic = optic:new(MapFold, Fold),
189 | optic:variations(Optic, Options, New).
190 |
--------------------------------------------------------------------------------
/src/optic_ordsets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to ordsets.
4 | %%%
5 | %%% As ordsets are internally represented as a plain list, the type
6 | %%% checks used here are not as reliable as those used for other
7 | %%% optics. Please ensure via other means that these optics are only
8 | %%% used with actual ordsets.
9 | %%% @end
10 | %%%-------------------------------------------------------------------
11 | -module(optic_ordsets).
12 |
13 | %% API
14 | -export([all/0,
15 | all/1]).
16 |
17 | %%%===================================================================
18 | %%% API
19 | %%%===================================================================
20 |
21 | %% @see all/1
22 | -spec all() -> optic:optic().
23 | all() ->
24 | all(#{}).
25 |
26 | %% @doc
27 | %% Focus on all elements of an ordset.
28 | %%
29 | %% Example:
30 | %%
31 | %% ```
32 | %% > optic:get([optic_ordsets:all()], ordsets:from_list([1,2,3])).
33 | %% {ok,[1,2,3]}
34 | %% '''
35 | %% @end
36 | %% @param Options Common optic options.
37 | %% @returns An opaque optic record.
38 | -spec all(Options) -> optic:optic() when
39 | Options :: optic:variations().
40 | all(Options) ->
41 | Fold =
42 | fun (Fun, Acc, Set) ->
43 | case is_ordset(Set) of
44 | true ->
45 | {ok, ordsets:fold(Fun, Acc, Set)};
46 | false ->
47 | {error, undefined}
48 | end
49 | end,
50 | MapFold =
51 | fun (Fun, Acc, Set) ->
52 | case is_ordset(Set) of
53 | true ->
54 | {ok, ordsets:fold(fun (Elem, {InnerSet, InnerAcc}) ->
55 | {NewElem, NewAcc} = Fun(Elem, InnerAcc),
56 | {ordsets:add_element(NewElem, InnerSet), NewAcc}
57 | end,
58 | {ordsets:new(), Acc},
59 | Set)};
60 | false ->
61 | {error, undefined}
62 | end
63 | end,
64 | New =
65 | fun (_Data, _Template) ->
66 | ordsets:new()
67 | end,
68 | Optic = optic:new(MapFold, Fold),
69 | optic:variations(Optic, Options, New).
70 |
71 | %%%===================================================================
72 | %%% Internal Functions
73 | %%%===================================================================
74 |
75 | is_ordset(Unknown) when is_list(Unknown) ->
76 | true;
77 | is_ordset(_Unknown) ->
78 | false.
79 |
--------------------------------------------------------------------------------
/src/optic_path.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Utility functions for constructing optics from lists of selectors.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_path).
7 |
8 | -type path() :: string() | binary() | non_neg_integer() | '*'.
9 | %% A single path component.
10 | -type paths() :: [path()].
11 | %% A list of path components.
12 |
13 | %% API
14 | -export([new/1]).
15 |
16 | -export_type([path/0,
17 | paths/0]).
18 |
19 | %%%===================================================================
20 | %%% API
21 | %%%===================================================================
22 |
23 | %% @doc
24 | %% Construct a list of optics from a path. The type of the path
25 | %% component determines the optic used:
26 | %%
27 | %%
28 | %% string: A key for a map-like structure.
29 | %% binary: A key for a map-like structure.
30 | %% integer: An index into a list-like structure.
31 | %% '*': All elements of a list.
32 | %%
33 | %%
34 | %% This heavily depends on the `optic_generic' module, see the optics
35 | %% there for the full list of containers supported.
36 | %%
37 | %% Example:
38 | %%
39 | %% ```
40 | %% > optic:get(optic_path(["first"]), ${"first" => 1, "second" => 2}).
41 | %% {ok,[1]}
42 | %% '''
43 | %% @end
44 | %% @param Paths A list of path components to convert.
45 | %% @returns A list of opaque optic records.
46 | -spec new(Paths) -> optic:optics() when
47 | Paths :: paths().
48 | new([]) ->
49 | [];
50 | new([Path | Paths]) when is_list(Path); is_binary(Path) ->
51 | [optic_generic:key(Path) | new(Paths)];
52 | new([Path | Paths]) when is_integer(Path), Path > 0 ->
53 | [optic_generic:index(Path) | new(Paths)];
54 | new(['*' | Paths]) ->
55 | [optic_lists:all() | new(Paths)].
56 |
--------------------------------------------------------------------------------
/src/optic_sets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to sets.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_sets).
7 |
8 | %% API
9 | -export([all/0,
10 | all/1]).
11 |
12 | %%%===================================================================
13 | %%% API
14 | %%%===================================================================
15 |
16 | %% @see all/1
17 | -spec all() -> optic:optic().
18 | all() ->
19 | all(#{}).
20 |
21 | %% @doc
22 | %% Focus on all elements of a set.
23 | %%
24 | %% Example:
25 | %%
26 | %% ```
27 | %% > optic:get([optic_sets:all()], sets:from_list([1,2,3])).
28 | %% {ok,[1,2,3]}
29 | %% '''
30 | %% @end
31 | %% @param Options Common optic options.
32 | %% @returns An opaque optic record.
33 | -spec all(Options) -> optic:optic() when
34 | Options :: optic:variations().
35 | all(Options) ->
36 | Fold =
37 | fun (Fun, Acc, Set) ->
38 | case is_set(Set) of
39 | true ->
40 | {ok, sets:fold(Fun, Acc, Set)};
41 | false ->
42 | {error, undefined}
43 | end
44 | end,
45 | MapFold =
46 | fun (Fun, Acc, Set) ->
47 | case is_set(Set) of
48 | true ->
49 | {ok, sets:fold(fun (Elem, {InnerSet, InnerAcc}) ->
50 | {NewElem, NewAcc} = Fun(Elem, InnerAcc),
51 | {sets:add_element(NewElem, InnerSet), NewAcc}
52 | end,
53 | {sets:new(), Acc},
54 | Set)};
55 | false ->
56 | {error, undefined}
57 | end
58 | end,
59 | New =
60 | fun (_Data, _Template) ->
61 | sets:new()
62 | end,
63 | Optic = optic:new(MapFold, Fold),
64 | optic:variations(Optic, Options, New).
65 |
66 | %%%===================================================================
67 | %%% Internal Functions
68 | %%%===================================================================
69 |
70 | is_set(Unknown) ->
71 | try sets:size(Unknown) of
72 | _ ->
73 | true
74 | catch
75 | error:{badrecord, set} ->
76 | false
77 | end.
78 |
--------------------------------------------------------------------------------
/src/optic_tuples.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% A set of optics specific to tuples.
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(optic_tuples).
7 |
8 | %% API
9 | -export([all/0,
10 | all/1,
11 | element/1,
12 | element/2,
13 | field/3,
14 | field/4]).
15 |
16 | %%%===================================================================
17 | %%% API
18 | %%%===================================================================
19 |
20 | %% @see all/1
21 | -spec all() -> optic:optic().
22 | all() ->
23 | all(#{}).
24 |
25 | %% @doc
26 | %% Focus on all elements of a tuple.
27 | %%
28 | %% Example:
29 | %%
30 | %% ```
31 | %% > optic:get([optic_tuples:all()], {1,2,3}).
32 | %% {ok,[1,2,3]}
33 | %% '''
34 | %% @end
35 | %% @param Options Common optic options.
36 | %% @returns An opaque optic record.
37 | -spec all(Options) -> optic:optic() when
38 | Options :: optic:variations().
39 | all(Options) ->
40 | Fold =
41 | fun (Fun, Acc, Tuple) when is_tuple(Tuple) ->
42 | {ok, lists:foldl(Fun, Acc, tuple_to_list(Tuple))};
43 | (_, _, _) ->
44 | {error, undefined}
45 | end,
46 | MapFold =
47 | fun (Fun, Acc, Tuple) when is_tuple(Tuple) ->
48 | {NewList, NewAcc} = lists:mapfoldl(Fun, Acc, tuple_to_list(Tuple)),
49 | {ok, {list_to_tuple(NewList), NewAcc}};
50 | (_, _, _) ->
51 | {error, undefined}
52 | end,
53 | New =
54 | fun (_Data, _Template) ->
55 | {}
56 | end,
57 | Optic = optic:new(MapFold, Fold),
58 | optic:variations(Optic, Options, New).
59 |
60 | %% @see element/2
61 | -spec element(N) -> optic:optic() when
62 | N :: pos_integer().
63 | element(N) ->
64 | optic_tuples:element(N, #{}).
65 |
66 | %% @doc
67 | %% Focus on the nth element of a tuple. As with `erlang:element/2',
68 | %% indexing begins at 1.
69 | %%
70 | %% Example:
71 | %%
72 | %% ```
73 | %% > optic:get([optic_tuples:element(1)], {1,2,3}).
74 | %% {ok,[1]}
75 | %% '''
76 | %% @end
77 | %% @param N The index of the tuple element to focus on.
78 | %% @param Options Common optic options.
79 | %% @returns An opaque optic record.
80 | -spec element(N, Options) -> optic:optic() when
81 | N :: pos_integer(),
82 | Options :: optic:variations().
83 | element(N, Options) ->
84 | Fold =
85 | fun (Fun, Acc, Tuple) when N =< tuple_size(Tuple) ->
86 | Nth = erlang:element(N, Tuple),
87 | {ok, Fun(Nth, Acc)};
88 | (_, _, _) ->
89 | {error, undefined}
90 | end,
91 | MapFold =
92 | fun (Fun, Acc, Tuple) when N =< tuple_size(Tuple) ->
93 | Nth = erlang:element(N, Tuple),
94 | {NewNth, NewAcc} = Fun(Nth, Acc),
95 | {ok, {erlang:setelement(N, Tuple, NewNth), NewAcc}};
96 | (_, _, _) ->
97 | {error, undefined}
98 | end,
99 | New =
100 | fun (Tuple, Template) when is_tuple(Tuple) ->
101 | list_to_tuple(tuple_to_list(Tuple) ++
102 | lists:duplicate(N - tuple_size(Tuple), Template));
103 | (_Data, Template) ->
104 | list_to_tuple(lists:duplicate(N, Template))
105 | end,
106 | Optic = optic:new(MapFold, Fold),
107 | optic:variations(Optic, Options, New).
108 |
109 | %% @see field/4
110 | -spec field(Tag, Size, N) -> optic:optic() when
111 | Tag :: atom(),
112 | Size :: pos_integer(),
113 | N :: pos_integer().
114 | field(Tag, Size, N) ->
115 | field(Tag, Size, N, #{}).
116 |
117 | %% @doc
118 | %% Focus on a record field. As records are a compiler construct, this
119 | %% depends on the `?OPTIC_FIELD' macro in `include/optic_tuples.hrl'
120 | %% to construct the required arguments from the record definition.
121 | %%
122 | %% Given the record definition:
123 | %%
124 | %% ```
125 | %% -include_lib("optic/include/optic_tuples.hrl").
126 | %% -record(example, {first}).
127 | %% '''
128 | %%
129 | %% Example:
130 | %%
131 | %% ```
132 | %% > optic:get([optic_tuples:field(?OPTIC_FIELD(example, first))],
133 | %% #example{first=1}).
134 | %% {ok,[1]}
135 | %% '''
136 | %% @end
137 | %% @param Tag The expected record tag.
138 | %% @param Size The expected record size.
139 | %% @param N The index of the field in the record tuple.
140 | %% @param Options Common optic options.
141 | %% @returns An opaque optic record.
142 | -spec field(Tag, Size, N, Options) -> optic:optic() when
143 | Tag :: atom(),
144 | Size :: pos_integer(),
145 | N :: pos_integer(),
146 | Options :: optic:variations().
147 | field(Tag, Size, N, Options) ->
148 | Fold =
149 | fun (Fun, Acc, Tuple) when erlang:element(1, Tuple) == Tag,
150 | Size == tuple_size(Tuple),
151 | N > 1,
152 | N =< tuple_size(Tuple) ->
153 | Nth = erlang:element(N, Tuple),
154 | {ok, Fun(Nth, Acc)};
155 | (_, _, _) ->
156 | {error, undefined}
157 | end,
158 | MapFold =
159 | fun (Fun, Acc, Tuple) when erlang:element(1, Tuple) == Tag,
160 | Size == tuple_size(Tuple),
161 | N > 1,
162 | N =< tuple_size(Tuple) ->
163 | Nth = erlang:element(N, Tuple),
164 | {NewNth, NewAcc} = Fun(Nth, Acc),
165 | {ok, {erlang:setelement(N, Tuple, NewNth), NewAcc}};
166 | (_, _, _) ->
167 | {error, undefined}
168 | end,
169 | New =
170 | fun (_Data, Template) ->
171 | list_to_tuple([Tag] ++ lists:duplicate(Size - 1, Template))
172 | end,
173 | Optic = optic:new(MapFold, Fold),
174 | optic:variations(Optic, Options, New).
175 |
--------------------------------------------------------------------------------
/test/test_optic_array.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_array.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_array).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | optic:get([optic_array:all([strict])],
17 | array:from_list([1, 2, 3]))),
18 | ?_assertEqual({error, undefined},
19 | optic:get([optic_array:all([strict])],
20 | atom))].
21 |
22 | all_put_test_() ->
23 | [?_assertEqual({ok, array:from_list([4, 4, 4])},
24 | optic:put([optic_array:all([strict])],
25 | 4,
26 | array:from_list([1, 2, 3]))),
27 | ?_assertEqual({error, undefined},
28 | optic:put([optic_array:all([strict])],
29 | 4,
30 | atom))].
31 |
32 | all_create_test() ->
33 | ?assertEqual({ok, array:new([{default, test}])},
34 | optic:put([optic_array:all([strict, {create, test}])],
35 | 4,
36 | atom)).
37 |
38 | nth_get_test_() ->
39 | [?_assertEqual({ok, [1]},
40 | optic:get([optic_array:nth(1, [strict])],
41 | array:from_list([1, 2, 3]))),
42 | ?_assertEqual({error, undefined},
43 | optic:get([optic_array:nth(1, [strict])],
44 | atom))].
45 |
46 | nth_put_test_() ->
47 | [?_assertEqual({ok, array:from_list([4, 2, 3])},
48 | optic:put([optic_array:nth(1, [strict])],
49 | 4,
50 | array:from_list([1, 2, 3]))),
51 | ?_assertEqual({error, undefined},
52 | optic:put([optic_array:nth(1, [strict])],
53 | 4,
54 | atom))].
55 |
56 | nth_create_test_() ->
57 | [?_assertEqual({ok, [test, 4]},
58 | maybe_to_list(
59 | optic:put([optic_array:nth(2, [strict, {create, test}])],
60 | 4,
61 | atom))),
62 | ?_assertEqual({ok, [1, undefined, 4]},
63 | maybe_to_list(
64 | optic:put([optic_array:nth(3, [strict, create])],
65 | 4,
66 | array:from_list([1]))))].
67 |
68 | %%%===================================================================
69 | %%% Internal Functions
70 | %%%===================================================================
71 |
72 | maybe_to_list({ok, Result}) ->
73 | {ok, array:to_list(Result)}.
74 |
--------------------------------------------------------------------------------
/test/test_optic_dict.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_dict.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_dict).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(
17 | optic:get([optic_dict:all([strict])],
18 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
19 | ?_assertEqual({error, undefined},
20 | optic:get([optic_dict:all([strict])], atom))].
21 |
22 | all_put_test_() ->
23 | [?_assertEqual({ok, dict:from_list([{one, 4}, {two, 4}, {three, 4}])},
24 | optic:put([optic_dict:all([strict])],
25 | 4,
26 | dict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
27 | ?_assertEqual({error, undefined},
28 | optic:put([optic_dict:all([strict])], 4, atom))].
29 |
30 | all_create_test() ->
31 | ?assertEqual({ok, dict:new()},
32 | optic:put([optic_dict:all([strict, create])], 4, atom)).
33 |
34 | keys_get_test_() ->
35 | [?_assertEqual({ok, [one, three, two]},
36 | sort_get(
37 | optic:get([optic_dict:keys([strict])],
38 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
39 | ?_assertEqual({error, undefined},
40 | optic:get([optic_dict:keys([strict])], atom))].
41 |
42 | keys_put_test_() ->
43 | [?_assertEqual({ok, dict:from_list([{four, 1}])},
44 | optic:put([optic_dict:keys([strict])],
45 | four,
46 | dict:from_list([{one, 1}]))),
47 | ?_assertEqual({error, undefined},
48 | optic:put([optic_dict:keys([strict])], four, atom))].
49 |
50 | keys_create_test() ->
51 | ?assertEqual({ok, dict:new()},
52 | optic:put([optic_dict:keys([strict, create])], four, atom)).
53 |
54 | values_get_test_() ->
55 | [?_assertEqual({ok, [1, 2, 3]},
56 | sort_get(
57 | optic:get([optic_dict:values([strict])],
58 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
59 | ?_assertEqual({error, undefined},
60 | optic:get([optic_dict:values([strict])], atom))].
61 |
62 | values_put_test_() ->
63 | [?_assertEqual({ok, dict:from_list([{one, 4}, {two, 4}, {three, 4}])},
64 | optic:put([optic_dict:values([strict])],
65 | 4,
66 | dict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
67 | ?_assertEqual({error, undefined},
68 | optic:put([optic_dict:values([strict])], 4, atom))].
69 |
70 | values_create_test() ->
71 | ?assertEqual({ok, dict:new()},
72 | optic:put([optic_dict:values([strict, create])], 4, atom)).
73 |
74 | associations_get_test_() ->
75 | [?_assertEqual({ok, [{one, 1}, {three, 3}, {two, 2}]},
76 | sort_get(
77 | optic:get([optic_dict:associations([strict])],
78 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
79 | ?_assertEqual({error, undefined},
80 | optic:get([optic_dict:associations([strict])], atom))].
81 |
82 | associations_put_test_() ->
83 | [?_assertEqual({ok, dict:from_list([{four, 4}])},
84 | optic:put([optic_dict:associations([strict])],
85 | {four, 4},
86 | dict:from_list([{one, 1}]))),
87 | ?_assertEqual({error, undefined},
88 | optic:put([optic_dict:associations([strict])],
89 | {four, 4},
90 | atom))].
91 |
92 | associations_create_test() ->
93 | ?assertEqual({ok, dict:new()},
94 | optic:put([optic_dict:associations([strict, create])],
95 | {four, 4},
96 | atom)).
97 |
98 | key_get_test_() ->
99 | [?_assertEqual({ok, [1]},
100 | sort_get(
101 | optic:get([optic_dict:key(one, [strict])],
102 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
103 | ?_assertEqual({error, undefined},
104 | optic:get([optic_dict:key(one, [strict])], atom))].
105 |
106 | key_put_test_() ->
107 | [?_assertEqual({ok, dict:from_list([{one, 4}, {two, 2}, {three, 3}])},
108 | optic:put([optic_dict:key(one, [strict])],
109 | 4,
110 | dict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
111 | ?_assertEqual({error, undefined},
112 | optic:put([optic_dict:key(one, [strict])], 4, atom))].
113 |
114 | key_create_test_() ->
115 | [?_assertEqual({ok, dict:from_list([{one, 1}, {four, 4}])},
116 | optic:put([optic_dict:key(four, [strict, create])],
117 | 4,
118 | dict:from_list([{one, 1}]))),
119 | ?_assertEqual({ok, dict:from_list([{four, 4}])},
120 | optic:put([optic_dict:key(four, [strict, create])],
121 | 4,
122 | atom))].
123 |
124 | association_get_test_() ->
125 | [?_assertEqual({ok, [{one, 1}]},
126 | sort_get(
127 | optic:get([optic_dict:association(one, [strict])],
128 | dict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
129 | ?_assertEqual({error, undefined},
130 | optic:get([optic_dict:association(one, [strict])], atom))].
131 |
132 | association_put_test_() ->
133 | [?_assertEqual({ok, dict:from_list([{two, 2}, {three, 3}, {four, 4}])},
134 | optic:put([optic_dict:association(one, [strict])],
135 | {four, 4},
136 | dict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
137 | ?_assertEqual({ok, dict:from_list([{two, 2}, {three, 3}, {four, 4}])},
138 | optic:put([optic_dict:association(one, [strict])],
139 | {four, 4},
140 | dict:from_list([{one, 1}, {two, 2}, {three, 3}, {four, clobbered}]))),
141 | ?_assertEqual({error, undefined},
142 | optic:put([optic_dict:association(one, [strict])],
143 | 4,
144 | atom))].
145 |
146 | association_create_test_() ->
147 | [?_assertEqual({ok, dict:from_list([{one, 1}, {four, 4}])},
148 | optic:put([optic_dict:association(four, [strict, create])],
149 | {four, 4},
150 | dict:from_list([{one, 1}]))),
151 | ?_assertEqual({ok, dict:from_list([{four, 4}])},
152 | optic:put([optic_dict:association(four, [strict, create])],
153 | {four, 4},
154 | atom))].
155 |
156 | %%%===================================================================
157 | %%% Internal Functions
158 | %%%===================================================================
159 |
160 | sort_get({ok, Result}) ->
161 | {ok, lists:sort(Result)}.
162 |
--------------------------------------------------------------------------------
/test/test_optic_gb_sets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_gb_sets.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_gb_sets).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(
17 | optic:get([optic_gb_sets:all([strict])],
18 | gb_sets:from_list([1, 2, 3])))),
19 | ?_assertEqual({error, undefined},
20 | optic:get([optic_gb_sets:all([strict])], atom))].
21 |
22 | all_map_test() ->
23 | ?assertEqual({ok, [2, 4, 6]},
24 | sort_put(
25 | optic:map([optic_gb_sets:all([strict])],
26 | fun (Elem) -> Elem * 2 end,
27 | gb_sets:from_list([1, 2, 3])))).
28 |
29 | all_put_test_() ->
30 | [?_assertEqual({ok, [4]},
31 | sort_put(
32 | optic:put([optic_gb_sets:all([strict])],
33 | 4,
34 | gb_sets:from_list([1, 2, 3])))),
35 | ?_assertEqual({error, undefined},
36 | optic:put([optic_gb_sets:all([strict])], 4, atom))].
37 |
38 | all_create_test() ->
39 | ?assertEqual({ok, gb_sets:new()},
40 | optic:put([optic_gb_sets:all([strict, create])],
41 | 4,
42 | atom)).
43 |
44 | %%%===================================================================
45 | %%% Internal Functions
46 | %%%===================================================================
47 |
48 | sort_get({ok, Result}) ->
49 | {ok, lists:sort(Result)}.
50 |
51 | sort_put({ok, Result}) ->
52 | {ok, lists:sort(gb_sets:to_list(Result))}.
53 |
--------------------------------------------------------------------------------
/test/test_optic_gb_trees.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_gb_trees.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_gb_trees).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(
17 | optic:get([optic_gb_trees:all([strict])],
18 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
19 | ?_assertEqual({error, undefined},
20 | optic:get([optic_gb_trees:all([strict])], atom))].
21 |
22 | all_put_test_() ->
23 | [?_assertEqual({ok, [{one, 4}, {three, 4}, {two, 4}]},
24 | sort_put(
25 | optic:put([optic_gb_trees:all([strict])],
26 | 4,
27 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
28 | ?_assertEqual({error, undefined},
29 | optic:put([optic_gb_trees:all([strict])], 4, atom))].
30 |
31 | all_create_test() ->
32 | ?assertEqual({ok, []},
33 | sort_put(
34 | optic:put([optic_gb_trees:all([strict, create])], 4, atom))).
35 |
36 | keys_get_test_() ->
37 | [?_assertEqual({ok, [one, three, two]},
38 | sort_get(
39 | optic:get([optic_gb_trees:keys([strict])],
40 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
41 | ?_assertEqual({error, undefined},
42 | optic:get([optic_gb_trees:keys([strict])], atom))].
43 |
44 | keys_put_test_() ->
45 | [?_assertEqual({ok, [{four, 1}]},
46 | sort_put(
47 | optic:put([optic_gb_trees:keys([strict])],
48 | four,
49 | from_list([{one, 1}])))),
50 | ?_assertEqual({error, undefined},
51 | optic:put([optic_gb_trees:keys([strict])], four, atom))].
52 |
53 | keys_create_test() ->
54 | ?assertEqual({ok, []},
55 | sort_put(
56 | optic:put([optic_gb_trees:keys([strict, create])], four, atom))).
57 |
58 | values_get_test_() ->
59 | [?_assertEqual({ok, [1, 2, 3]},
60 | sort_get(
61 | optic:get([optic_gb_trees:values([strict])],
62 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
63 | ?_assertEqual({error, undefined},
64 | optic:get([optic_gb_trees:values([strict])], atom))].
65 |
66 | values_put_test_() ->
67 | [?_assertEqual({ok, [{one, 4}, {three, 4}, {two, 4}]},
68 | sort_put(
69 | optic:put([optic_gb_trees:values([strict])],
70 | 4,
71 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
72 | ?_assertEqual({error, undefined},
73 | optic:put([optic_gb_trees:values([strict])], 4, atom))].
74 |
75 | values_create_test() ->
76 | ?assertEqual({ok, []},
77 | sort_put(
78 | optic:put([optic_gb_trees:values([strict, create])], 4, atom))).
79 |
80 | associations_get_test_() ->
81 | [?_assertEqual({ok, [{one, 1}, {three, 3}, {two, 2}]},
82 | sort_get(
83 | optic:get([optic_gb_trees:associations([strict])],
84 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
85 | ?_assertEqual({error, undefined},
86 | optic:get([optic_gb_trees:associations([strict])], atom))].
87 |
88 | associations_put_test_() ->
89 | [?_assertEqual({ok, [{four, 4}]},
90 | sort_put(
91 | optic:put([optic_gb_trees:associations([strict])],
92 | {four, 4},
93 | from_list([{one, 1}])))),
94 | ?_assertEqual({error, undefined},
95 | optic:put([optic_gb_trees:associations([strict])],
96 | {four, 4},
97 | atom))].
98 |
99 | associations_create_test() ->
100 | ?assertEqual({ok, []},
101 | sort_put(
102 | optic:put([optic_gb_trees:associations([strict, create])],
103 | {four, 4},
104 | atom))).
105 |
106 | key_get_test_() ->
107 | [?_assertEqual({ok, [1]},
108 | sort_get(
109 | optic:get([optic_gb_trees:key(one, [strict])],
110 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
111 | ?_assertEqual({error, undefined},
112 | optic:get([optic_gb_trees:key(one, [strict])], atom))].
113 |
114 | key_put_test_() ->
115 | [?_assertEqual({ok, [{one, 4}, {three, 3}, {two, 2}]},
116 | sort_put(
117 | optic:put([optic_gb_trees:key(one, [strict])],
118 | 4,
119 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
120 | ?_assertEqual({error, undefined},
121 | optic:put([optic_gb_trees:key(one, [strict])], 4, atom))].
122 |
123 | key_create_test_() ->
124 | [?_assertEqual({ok, [{four, 4}, {one, 1}]},
125 | sort_put(
126 | optic:put([optic_gb_trees:key(four, [strict, create])],
127 | 4,
128 | from_list([{one, 1}])))),
129 | ?_assertEqual({ok, [{four, 4}]},
130 | sort_put(
131 | optic:put([optic_gb_trees:key(four, [strict, create])],
132 | 4,
133 | atom)))].
134 |
135 | association_get_test_() ->
136 | [?_assertEqual({ok, [{one, 1}]},
137 | sort_get(
138 | optic:get([optic_gb_trees:association(one, [strict])],
139 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
140 | ?_assertEqual({error, undefined},
141 | optic:get([optic_gb_trees:association(one, [strict])], atom))].
142 |
143 | association_put_test_() ->
144 | [?_assertEqual({ok, [{four, 4}, {three, 3}, {two, 2}]},
145 | sort_put(
146 | optic:put([optic_gb_trees:association(one, [strict])],
147 | {four, 4},
148 | from_list([{one, 1}, {two, 2}, {three, 3}])))),
149 | ?_assertEqual({ok, [{four, 4}, {three, 3}, {two, 2}]},
150 | sort_put(
151 | optic:put([optic_gb_trees:association(one, [strict])],
152 | {four, 4},
153 | from_list([{one, 1}, {two, 2}, {three, 3}, {four, clobbered}])))),
154 | ?_assertEqual({error, undefined},
155 | optic:put([optic_gb_trees:association(one, [strict])],
156 | 4,
157 | atom))].
158 |
159 | association_create_test_() ->
160 | [?_assertEqual({ok, [{four, 4}, {one, 1}]},
161 | sort_put(
162 | optic:put([optic_gb_trees:association(four, [strict, create])],
163 | {four, 4},
164 | from_list([{one, 1}])))),
165 | ?_assertEqual({ok, [{four, 4}]},
166 | sort_put(
167 | optic:put([optic_gb_trees:association(four, [strict, create])],
168 | {four, 4},
169 | atom)))].
170 |
171 | %%%===================================================================
172 | %%% Internal Functions
173 | %%%===================================================================
174 |
175 | from_list(List) ->
176 | Dict = orddict:from_list(List),
177 | gb_trees:from_orddict(Dict).
178 |
179 | sort_get({ok, Result}) ->
180 | {ok, lists:sort(Result)}.
181 |
182 | sort_put({ok, Result}) ->
183 | {ok, gb_trees:to_list(Result)}.
184 |
--------------------------------------------------------------------------------
/test/test_optic_generic.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_generic.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_generic).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | key_get_test_() ->
15 | [?_assertEqual({ok, [value]},
16 | optic:get([optic_generic:key(key)], #{key=>value})),
17 | ?_assertEqual({ok, [value]},
18 | optic:get([optic_generic:key(key)], [{key, value}])),
19 | ?_assertEqual({ok, [value]},
20 | optic:get([optic_generic:key(key)], orddict:from_list([{key, value}]))),
21 | ?_assertEqual({ok, [value]},
22 | optic:get([optic_generic:key(key)], dict:from_list([{key, value}]))),
23 | ?_assertEqual({ok, [value]},
24 | optic:get([optic_generic:key(key)], gb_trees:from_orddict([{key, value}]))),
25 | ?_assertEqual({ok, []},
26 | optic:get([optic_generic:key(key)], atom))].
27 |
28 | key_put_test_() ->
29 | [?_assertEqual({ok, #{key=>new}},
30 | optic:put([optic_generic:key(key)], new, #{key=>value})),
31 | ?_assertEqual({ok, [{key, new}]},
32 | optic:put([optic_generic:key(key)], new, [{key, value}])),
33 | ?_assertEqual({ok, [{key, new}]},
34 | optic:put([optic_generic:key(key)], new, orddict:from_list([{key, value}]))),
35 | ?_assertEqual({ok, dict:from_list([{key, new}])},
36 | optic:put([optic_generic:key(key)], new, dict:from_list([{key, value}]))),
37 | ?_assertEqual({ok, gb_trees:from_orddict([{key, new}])},
38 | optic:put([optic_generic:key(key)], new, gb_trees:from_orddict([{key, value}]))),
39 | ?_assertEqual({ok, atom},
40 | optic:put([optic_generic:key(key)], new, atom))].
41 |
42 | index_get_test_() ->
43 | [?_assertEqual({ok, [3]},
44 | optic:get([optic_generic:index(3)], [1, 2, 3])),
45 | ?_assertEqual({ok, [3]},
46 | optic:get([optic_generic:index(3)], {1, 2, 3})),
47 | ?_assertEqual({ok, []},
48 | optic:get([optic_generic:index(3)], #{}))].
49 |
50 | index_put_test_() ->
51 | [?_assertEqual({ok, [1, 2, 4]},
52 | optic:put([optic_generic:index(3)], 4, [1, 2, 3])),
53 | ?_assertEqual({ok, {1, 2, 4}},
54 | optic:put([optic_generic:index(3)], 4, {1, 2, 3})),
55 | ?_assertEqual({ok, #{}},
56 | optic:put([optic_generic:index(3)], 4, #{}))].
57 |
--------------------------------------------------------------------------------
/test/test_optic_lists.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_lists.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_lists).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | optic:get([optic_lists:all([strict])], [1, 2, 3])),
17 | ?_assertEqual({ok, [3]},
18 | optic:get([optic_lists:all([strict,
19 | {filter,
20 | fun (Elem) -> Elem == 3 end}])],
21 | [1, 2, 3])),
22 | ?_assertEqual({ok, [3]},
23 | optic:get([optic_lists:all([strict,
24 | {require,
25 | fun (Elem) -> Elem == 3 end}])],
26 | [3])),
27 | ?_assertEqual({error, required},
28 | optic:get([optic_lists:all([create,
29 | {require,
30 | fun (Elem) -> Elem == 3 end}])],
31 | [1, 2, 3])),
32 | ?_assertEqual({ok, []},
33 | optic:get([optic_lists:all()], atom)),
34 | ?_assertEqual({ok, []},
35 | optic:get([optic_lists:all([{strict, false}])], atom)),
36 | ?_assertEqual({error, undefined},
37 | optic:get([optic_lists:all([strict])], atom))].
38 |
39 | all_put_test_() ->
40 | [?_assertEqual({ok, [4, 4, 4]},
41 | optic:put([optic_lists:all([strict])], 4, [1, 2, 3])),
42 | ?_assertEqual({ok, [1, 2, 4]},
43 | optic:put([optic_lists:all([strict,
44 | {filter,
45 | fun (Elem) -> Elem == 3 end}])],
46 | 4,
47 | [1, 2, 3])),
48 | ?_assertEqual({ok, [4]},
49 | optic:put([optic_lists:all([strict,
50 | {require,
51 | fun (Elem) -> Elem == 3 end}])],
52 | 4,
53 | [3])),
54 | ?_assertEqual({error, required},
55 | optic:put([optic_lists:all([create,
56 | {require,
57 | fun (Elem) -> Elem == 3 end}])],
58 | 4,
59 | [1, 2, 3])),
60 | ?_assertEqual({ok, atom},
61 | optic:put([optic_lists:all()], 4, atom)),
62 | ?_assertEqual({ok, atom},
63 | optic:put([optic_lists:all([{strict, false}])], 4, atom)),
64 | ?_assertEqual({error, undefined},
65 | optic:put([optic_lists:all([strict])], 4, atom))].
66 |
67 | all_create_test() ->
68 | ?assertEqual({ok, []},
69 | optic:put([optic_lists:all([strict, create])], 4, atom)).
70 |
71 | head_get_test_() ->
72 | [?_assertEqual({ok, [1]},
73 | optic:get([optic_lists:head([strict])], [1, 2, 3])),
74 | ?_assertEqual({error, undefined},
75 | optic:get([optic_lists:head([strict])], atom))].
76 |
77 | head_put_test_() ->
78 | [?_assertEqual({ok, [4, 2, 3]},
79 | optic:put([optic_lists:head([strict])], 4, [1, 2, 3])),
80 | ?_assertEqual({error, undefined},
81 | optic:put([optic_lists:head([strict])], 4, atom))].
82 |
83 | head_create_test() ->
84 | ?assertEqual({ok, [4]},
85 | optic:put([optic_lists:head([strict, create])], 4, atom)).
86 |
87 | tail_get_test_() ->
88 | [?_assertEqual({ok, [2, 3]},
89 | optic:get([optic_lists:tail([strict])], [1, 2, 3])),
90 | ?_assertEqual({error, undefined},
91 | optic:get([optic_lists:tail([strict])], atom))].
92 |
93 | tail_put_test_() ->
94 | [?_assertEqual({ok, [1, 4, 4]},
95 | optic:put([optic_lists:tail([strict])], 4, [1, 2, 3])),
96 | ?_assertEqual({error, undefined},
97 | optic:put([optic_lists:tail([strict])], 4, atom))].
98 |
99 | tail_create_test() ->
100 | ?assertEqual({ok, [undefined]},
101 | optic:put([optic_lists:tail([strict,
102 | {create, undefined}])],
103 | 4,
104 | atom)).
105 |
106 | nth_get_test_() ->
107 | [?_assertEqual({ok, [1]},
108 | optic:get([optic_lists:nth(1, [strict])], [1, 2, 3])),
109 | ?_assertEqual({error, undefined},
110 | optic:get([optic_lists:nth(1, [strict])], atom))].
111 |
112 | nth_put_test_() ->
113 | [?_assertEqual({ok, [4, 2, 3]},
114 | optic:put([optic_lists:nth(1, [strict])], 4, [1, 2, 3])),
115 | ?_assertEqual({error, undefined},
116 | optic:put([optic_lists:nth(1, [strict])], 4, atom))].
117 |
118 | nth_create_test_() ->
119 | [?_assertEqual({ok, [undefined, 4]},
120 | optic:put([optic_lists:nth(2, [strict,
121 | {create, undefined}])],
122 | 4,
123 | atom)),
124 | ?_assertEqual({ok, [1, undefined, 4]},
125 | optic:put([optic_lists:nth(3, [strict,
126 | {create, undefined}])],
127 | 4,
128 | [1]))].
129 |
--------------------------------------------------------------------------------
/test/test_optic_maps.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_maps.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_maps).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(optic:get([optic_maps:all([strict])],
17 | #{one=>1, two=>2, three=>3}))),
18 | ?_assertEqual({error, undefined},
19 | optic:get([optic_maps:all([strict])], atom))].
20 |
21 | all_put_test_() ->
22 | [?_assertEqual({ok, #{one=>4, two=>4, three=>4}},
23 | optic:put([optic_maps:all([strict])],
24 | 4,
25 | #{one=>1, two=>2, three=>3})),
26 | ?_assertEqual({error, undefined},
27 | optic:put([optic_maps:all([strict])], 4, atom))].
28 |
29 | all_create_test() ->
30 | ?assertEqual({ok, #{}},
31 | optic:put([optic_maps:all([strict, create])], 4, atom)).
32 |
33 | keys_get_test_() ->
34 | [?_assertEqual({ok, [one, three, two]},
35 | sort_get(optic:get([optic_maps:keys([strict])],
36 | #{one=>1, two=>2, three=>3}))),
37 | ?_assertEqual({error, undefined},
38 | optic:get([optic_maps:keys([strict])], atom))].
39 |
40 | keys_put_test_() ->
41 | [?_assertEqual({ok, #{four=>1}},
42 | optic:put([optic_maps:keys([strict])],
43 | four,
44 | #{one=>1})),
45 | ?_assertEqual({error, undefined},
46 | optic:put([optic_maps:keys([strict])], four, atom))].
47 |
48 | keys_create_test() ->
49 | ?assertEqual({ok, #{}},
50 | optic:put([optic_maps:keys([strict, create])], four, atom)).
51 |
52 | values_get_test_() ->
53 | [?_assertEqual({ok, [1, 2, 3]},
54 | sort_get(optic:get([optic_maps:values([strict])],
55 | #{one=>1, two=>2, three=>3}))),
56 | ?_assertEqual({error, undefined},
57 | optic:get([optic_maps:values([strict])], atom))].
58 |
59 | values_put_test_() ->
60 | [?_assertEqual({ok, #{one=>4, two=>4, three=>4}},
61 | optic:put([optic_maps:values([strict])],
62 | 4,
63 | #{one=>1, two=>2, three=>3})),
64 | ?_assertEqual({error, undefined},
65 | optic:put([optic_maps:values([strict])], 4, atom))].
66 |
67 | values_create_test() ->
68 | ?assertEqual({ok, #{}},
69 | optic:put([optic_maps:values([strict, create])], 4, atom)).
70 |
71 | associations_get_test_() ->
72 | [?_assertEqual({ok, [{one, 1}, {three, 3}, {two, 2}]},
73 | sort_get(optic:get([optic_maps:associations([strict])],
74 | #{one=>1, two=>2, three=>3}))),
75 | ?_assertEqual({error, undefined},
76 | optic:get([optic_maps:associations([strict])], atom))].
77 |
78 | associations_put_test_() ->
79 | [?_assertEqual({ok, #{four=>4}},
80 | optic:put([optic_maps:associations([strict])],
81 | {four, 4},
82 | #{one=>1})),
83 | ?_assertEqual({error, undefined},
84 | optic:put([optic_maps:associations([strict])],
85 | {four, 4},
86 | atom))].
87 |
88 | associations_create_test() ->
89 | ?assertEqual({ok, #{}},
90 | optic:put([optic_maps:associations([strict, create])],
91 | {four, 4},
92 | atom)).
93 |
94 | key_get_test_() ->
95 | [?_assertEqual({ok, [1]},
96 | sort_get(optic:get([optic_maps:key(one, [strict])],
97 | #{one=>1, two=>2, three=>3}))),
98 | ?_assertEqual({error, undefined},
99 | optic:get([optic_maps:key(one, [strict])], atom))].
100 |
101 | key_put_test_() ->
102 | [?_assertEqual({ok, #{one=>4, two=>2, three=>3}},
103 | optic:put([optic_maps:key(one, [strict])],
104 | 4,
105 | #{one=>1, two=>2, three=>3})),
106 | ?_assertEqual({error, undefined},
107 | optic:put([optic_maps:key(one, [strict])], 4, atom))].
108 |
109 | key_create_test_() ->
110 | [?_assertEqual({ok, #{one=>1, four=>4}},
111 | optic:put([optic_maps:key(four, [strict, create])],
112 | 4,
113 | #{one=>1})),
114 | ?_assertEqual({ok, #{four=>4}},
115 | optic:put([optic_maps:key(four, [strict, create])],
116 | 4,
117 | atom))].
118 |
119 | association_get_test_() ->
120 | [?_assertEqual({ok, [{one, 1}]},
121 | sort_get(optic:get([optic_maps:association(one, [strict])],
122 | #{one=>1, two=>2, three=>3}))),
123 | ?_assertEqual({error, undefined},
124 | optic:get([optic_maps:association(one, [strict])], atom))].
125 |
126 | association_put_test_() ->
127 | [?_assertEqual({ok, #{two=>2, three=>3, four=>4}},
128 | optic:put([optic_maps:association(one, [strict])],
129 | {four, 4},
130 | #{one=>1, two=>2, three=>3})),
131 | ?_assertEqual({ok, #{two=>2, three=>3, four=>4}},
132 | optic:put([optic_maps:association(one, [strict])],
133 | {four, 4},
134 | #{one=>1, two=>2, three=>3, four=>clobbered})),
135 | ?_assertEqual({error, undefined},
136 | optic:put([optic_maps:association(one, [strict])],
137 | 4,
138 | atom))].
139 |
140 | association_create_test_() ->
141 | [?_assertEqual({ok, #{one=>1, four=>4}},
142 | optic:put([optic_maps:association(four, [strict, create])],
143 | {four, 4},
144 | #{one=>1})),
145 | ?_assertEqual({ok, #{four=>4}},
146 | optic:put([optic_maps:association(four, [strict, create])],
147 | {four, 4},
148 | atom))].
149 |
150 | %%%===================================================================
151 | %%% Internal Functions
152 | %%%===================================================================
153 |
154 | sort_get({ok, Result}) ->
155 | {ok, lists:sort(Result)}.
156 |
--------------------------------------------------------------------------------
/test/test_optic_orddict.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_orddict.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_orddict).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(optic:get([optic_orddict:all([strict])],
17 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
18 | ?_assertEqual({error, undefined},
19 | optic:get([optic_orddict:all([strict])], atom))].
20 |
21 | all_put_test_() ->
22 | [?_assertEqual({ok, orddict:from_list([{one, 4}, {two, 4}, {three, 4}])},
23 | optic:put([optic_orddict:all([strict])],
24 | 4,
25 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
26 | ?_assertEqual({error, undefined},
27 | optic:put([optic_orddict:all([strict])], 4, atom))].
28 |
29 | all_create_test() ->
30 | ?assertEqual({ok, orddict:new()},
31 | optic:put([optic_orddict:all([strict, create])], 4, atom)).
32 |
33 | keys_get_test_() ->
34 | [?_assertEqual({ok, [one, three, two]},
35 | sort_get(optic:get([optic_orddict:keys([strict])],
36 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
37 | ?_assertEqual({error, undefined},
38 | optic:get([optic_orddict:keys([strict])], atom))].
39 |
40 | keys_put_test_() ->
41 | [?_assertEqual({ok, orddict:from_list([{four, 1}])},
42 | optic:put([optic_orddict:keys([strict])],
43 | four,
44 | orddict:from_list([{one, 1}]))),
45 | ?_assertEqual({error, undefined},
46 | optic:put([optic_orddict:keys([strict])], four, atom))].
47 |
48 | keys_create_test() ->
49 | ?assertEqual({ok, orddict:new()},
50 | optic:put([optic_orddict:keys([strict, create])], four, atom)).
51 |
52 | values_get_test_() ->
53 | [?_assertEqual({ok, [1, 2, 3]},
54 | sort_get(optic:get([optic_orddict:values([strict])],
55 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
56 | ?_assertEqual({error, undefined},
57 | optic:get([optic_orddict:values([strict])], atom))].
58 |
59 | values_put_test_() ->
60 | [?_assertEqual({ok, orddict:from_list([{one, 4}, {two, 4}, {three, 4}])},
61 | optic:put([optic_orddict:values([strict])],
62 | 4,
63 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
64 | ?_assertEqual({error, undefined},
65 | optic:put([optic_orddict:values([strict])], 4, atom))].
66 |
67 | values_create_test() ->
68 | ?assertEqual({ok, orddict:new()},
69 | optic:put([optic_orddict:values([strict, create])], 4, atom)).
70 |
71 | associations_get_test_() ->
72 | [?_assertEqual({ok, [{one, 1}, {three, 3}, {two, 2}]},
73 | sort_get(optic:get([optic_orddict:associations([strict])],
74 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
75 | ?_assertEqual({error, undefined},
76 | optic:get([optic_orddict:associations([strict])], atom))].
77 |
78 | associations_put_test_() ->
79 | [?_assertEqual({ok, orddict:from_list([{four, 4}])},
80 | optic:put([optic_orddict:associations([strict])],
81 | {four, 4},
82 | orddict:from_list([{one, 1}]))),
83 | ?_assertEqual({error, undefined},
84 | optic:put([optic_orddict:associations([strict])],
85 | {four, 4},
86 | atom))].
87 |
88 | associations_create_test() ->
89 | ?assertEqual({ok, orddict:new()},
90 | optic:put([optic_orddict:associations([strict, create])],
91 | {four, 4},
92 | atom)).
93 |
94 | key_get_test_() ->
95 | [?_assertEqual({ok, [1]},
96 | sort_get(optic:get([optic_orddict:key(one, [strict])],
97 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
98 | ?_assertEqual({error, undefined},
99 | optic:get([optic_orddict:key(one, [strict])], atom))].
100 |
101 | key_put_test_() ->
102 | [?_assertEqual({ok, orddict:from_list([{one, 4}, {two, 2}, {three, 3}])},
103 | optic:put([optic_orddict:key(one, [strict])],
104 | 4,
105 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
106 | ?_assertEqual({error, undefined},
107 | optic:put([optic_orddict:key(one, [strict])], 4, atom))].
108 |
109 | key_create_test_() ->
110 | [?_assertEqual({ok, orddict:from_list([{one, 1}, {four, 4}])},
111 | optic:put([optic_orddict:key(four, [strict, create])],
112 | 4,
113 | orddict:from_list([{one, 1}]))),
114 | ?_assertEqual({ok, orddict:from_list([{four, 4}])},
115 | optic:put([optic_orddict:key(four, [strict, create])],
116 | 4,
117 | atom))].
118 |
119 | association_get_test_() ->
120 | [?_assertEqual({ok, [{one, 1}]},
121 | sort_get(optic:get([optic_orddict:association(one, [strict])],
122 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}])))),
123 | ?_assertEqual({error, undefined},
124 | optic:get([optic_orddict:association(one, [strict])], atom))].
125 |
126 | association_put_test_() ->
127 | [?_assertEqual({ok, orddict:from_list([{two, 2}, {three, 3}, {four, 4}])},
128 | optic:put([optic_orddict:association(one, [strict])],
129 | {four, 4},
130 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}]))),
131 | ?_assertEqual({ok, orddict:from_list([{two, 2}, {three, 3}, {four, 4}])},
132 | optic:put([optic_orddict:association(one, [strict])],
133 | {four, 4},
134 | orddict:from_list([{one, 1}, {two, 2}, {three, 3}, {four, clobbered}]))),
135 | ?_assertEqual({error, undefined},
136 | optic:put([optic_orddict:association(one, [strict])],
137 | 4,
138 | atom))].
139 |
140 | association_create_test_() ->
141 | [?_assertEqual({ok, orddict:from_list([{one, 1}, {four, 4}])},
142 | optic:put([optic_orddict:association(four, [strict, create])],
143 | {four, 4},
144 | orddict:from_list([{one, 1}]))),
145 | ?_assertEqual({ok, orddict:from_list([{four, 4}])},
146 | optic:put([optic_orddict:association(four, [strict, create])],
147 | {four, 4},
148 | atom))].
149 |
150 | %%%===================================================================
151 | %%% Internal Functions
152 | %%%===================================================================
153 |
154 | sort_get({ok, Result}) ->
155 | {ok, lists:sort(Result)}.
156 |
--------------------------------------------------------------------------------
/test/test_optic_ordsets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_ordsets.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_ordsets).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(
17 | optic:get([optic_ordsets:all([strict])],
18 | ordsets:from_list([1, 2, 3])))),
19 | ?_assertEqual({error, undefined},
20 | optic:get([optic_ordsets:all([strict])], atom))].
21 |
22 | all_map_test() ->
23 | ?assertEqual({ok, [2, 4, 6]},
24 | sort_put(
25 | optic:map([optic_ordsets:all([strict])],
26 | fun (Elem) -> Elem * 2 end,
27 | ordsets:from_list([1, 2, 3])))).
28 |
29 | all_put_test_() ->
30 | [?_assertEqual({ok, [4]},
31 | sort_put(
32 | optic:put([optic_ordsets:all([strict])],
33 | 4,
34 | ordsets:from_list([1, 2, 3])))),
35 | ?_assertEqual({error, undefined},
36 | optic:put([optic_ordsets:all([strict])], 4, atom))].
37 |
38 | all_create_test() ->
39 | ?assertEqual({ok, ordsets:new()},
40 | optic:put([optic_ordsets:all([strict, create])],
41 | 4,
42 | atom)).
43 |
44 | %%%===================================================================
45 | %%% Internal Functions
46 | %%%===================================================================
47 |
48 | sort_get({ok, Result}) ->
49 | {ok, lists:sort(Result)}.
50 |
51 | sort_put({ok, Result}) ->
52 | {ok, lists:sort(ordsets:to_list(Result))}.
53 |
--------------------------------------------------------------------------------
/test/test_optic_path.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_path.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_path).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | new_test_() ->
15 | [?_assertEqual({ok, [value]},
16 | optic:get(optic_path:new(["key"]), #{"key"=>value})),
17 | ?_assertEqual({ok, [value]},
18 | optic:get(optic_path:new(["key"]), [{"key", value}])),
19 | ?_assertEqual({ok, [value]},
20 | optic:get(optic_path:new([<<"key">>]),
21 | #{<<"key">>=>value})),
22 | ?_assertEqual({ok, [value]},
23 | optic:get(optic_path:new([1]), [value])),
24 | ?_assertEqual({ok, [1, 2, 3]},
25 | optic:get(optic_path:new(['*']), [1, 2, 3])),
26 | ?_assertEqual({ok, [value]},
27 | optic:get(optic_path:new(["key", 1, "nested"]),
28 | #{"key"=>[#{"nested"=>value}]}))].
29 |
--------------------------------------------------------------------------------
/test/test_optic_proplists.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_proplists.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_proplists).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 1, 2, 3]},
16 | optic:get([optic_proplists:all([strict])],
17 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
18 | ?_assertEqual({error, undefined},
19 | optic:get([optic_proplists:all([strict])], atom))].
20 |
21 | all_put_test_() ->
22 | [?_assertEqual({ok, [{one, 4}, {one, 4}, {two, 4}, {three, 4}]},
23 | optic:put([optic_proplists:all([strict])],
24 | 4,
25 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
26 | ?_assertEqual({error, undefined},
27 | optic:put([optic_proplists:all([strict])], 4, atom))].
28 |
29 | all_create_test() ->
30 | ?assertEqual({ok, []},
31 | optic:put([optic_proplists:all([strict, create])], 4, atom)).
32 |
33 | keys_get_test_() ->
34 | [?_assertEqual({ok, [one, one, two, three]},
35 | optic:get([optic_proplists:keys([strict])],
36 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
37 | ?_assertEqual({error, undefined},
38 | optic:get([optic_proplists:keys([strict])], atom))].
39 |
40 | keys_put_test_() ->
41 | [?_assertEqual({ok, [{four, 1}, {four, 1}, {four, 2}, {four, 3}]},
42 | optic:put([optic_proplists:keys([strict])],
43 | four,
44 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
45 | ?_assertEqual({error, undefined},
46 | optic:put([optic_proplists:keys([strict])], four, atom))].
47 |
48 | keys_create_test() ->
49 | ?assertEqual({ok, []},
50 | optic:put([optic_proplists:keys([strict, create])],
51 | four,
52 | atom)).
53 |
54 | values_get_test_() ->
55 | [?_assertEqual({ok, [1, 1, 2, 3]},
56 | optic:get([optic_proplists:values([strict])],
57 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
58 | ?_assertEqual({error, undefined},
59 | optic:get([optic_proplists:values([strict])], atom))].
60 |
61 | values_put_test_() ->
62 | [?_assertEqual({ok, [{one, 4}, {one, 4}, {two, 4}, {three, 4}]},
63 | optic:put([optic_proplists:values([strict])],
64 | 4,
65 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
66 | ?_assertEqual({error, undefined},
67 | optic:put([optic_proplists:values([strict])], 4, atom))].
68 |
69 | values_create_test() ->
70 | ?assertEqual({ok, []},
71 | optic:put([optic_proplists:values([strict, create])],
72 | 4,
73 | atom)).
74 |
75 | properties_get_test_() ->
76 | [?_assertEqual({ok, [{one, 1}, {one, 1}, {two, 2}, {three, 3}]},
77 | optic:get([optic_proplists:properties([strict])],
78 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
79 | ?_assertEqual({error, undefined},
80 | optic:get([optic_proplists:properties([strict])], atom))].
81 |
82 | properties_put_test_() ->
83 | [?_assertEqual({ok, [{four, 4}, {four, 4}, {four, 4}, {four, 4}]},
84 | optic:put([optic_proplists:properties([strict])],
85 | {four, 4},
86 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
87 | ?_assertEqual({error, undefined},
88 | optic:put([optic_proplists:properties([strict])],
89 | four,
90 | atom))].
91 |
92 | properties_create_test() ->
93 | ?assertEqual({ok, []},
94 | optic:put([optic_proplists:properties([strict, create])],
95 | four,
96 | atom)).
97 |
98 | key_get_test_() ->
99 | [?_assertEqual({ok, [1, 1.5]},
100 | optic:get([optic_proplists:key(one, [strict])],
101 | [{one, 1}, {one, 1.5}, {two, 2}, {three, 3}])),
102 | ?_assertEqual({error, undefined},
103 | optic:get([optic_proplists:key(one, [strict])], atom))].
104 |
105 | key_put_test_() ->
106 | [?_assertEqual({ok, [{one, 4}, {one, 4}, {two, 2}, {three, 3}]},
107 | optic:put([optic_proplists:key(one, [strict])],
108 | 4,
109 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
110 | ?_assertEqual({error, undefined},
111 | optic:put([optic_proplists:key(one, [strict])], 4, atom))].
112 |
113 | key_create_test_() ->
114 | [?_assertEqual({ok, [{four, 4}, {one, 1}]},
115 | optic:put([optic_proplists:key(four, [strict, create])],
116 | 4,
117 | [{one, 1}])),
118 | ?_assertEqual({ok, [{four, 4}]},
119 | optic:put([optic_proplists:key(four, [strict, create])],
120 | 4,
121 | atom))].
122 |
123 | property_get_test_() ->
124 | [?_assertEqual({ok, [{one, 1}, {one, 1.5}]},
125 | optic:get([optic_proplists:property(one, [strict])],
126 | [{one, 1}, {one, 1.5}, {two, 2}, {three, 3}])),
127 | ?_assertEqual({error, undefined},
128 | optic:get([optic_proplists:property(one, [strict])],
129 | atom))].
130 |
131 | property_put_test_() ->
132 | [?_assertEqual({ok, [{four, 4}, {four, 4}, {two, 2}, {three, 3}]},
133 | optic:put([optic_proplists:property(one, [strict])],
134 | {four, 4},
135 | [{one, 1}, {one, 1}, {two, 2}, {three, 3}])),
136 | ?_assertEqual({error, undefined},
137 | optic:put([optic_proplists:property(one, [strict])],
138 | 4,
139 | atom))].
140 |
141 | property_create_test_() ->
142 | [?_assertEqual({ok, [{four, 4}, {one, 1}]},
143 | optic:put([optic_proplists:property(four, [strict, create])],
144 | {four, 4},
145 | [{one, 1}])),
146 | ?_assertEqual({ok, [{four, 4}]},
147 | optic:put([optic_proplists:property(four, [strict, create])],
148 | {four, 4},
149 | atom))].
150 |
--------------------------------------------------------------------------------
/test/test_optic_sets.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_sets.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_sets).
7 |
8 | -include_lib("eunit/include/eunit.hrl").
9 |
10 | %%%===================================================================
11 | %%% Tests
12 | %%%===================================================================
13 |
14 | all_get_test_() ->
15 | [?_assertEqual({ok, [1, 2, 3]},
16 | sort_get(
17 | optic:get([optic_sets:all([strict])],
18 | sets:from_list([1, 2, 3])))),
19 | ?_assertEqual({error, undefined},
20 | optic:get([optic_sets:all([strict])], atom))].
21 |
22 | all_map_test() ->
23 | ?assertEqual({ok, [2, 4, 6]},
24 | sort_put(
25 | optic:map([optic_sets:all([strict])],
26 | fun (Elem) -> Elem * 2 end,
27 | sets:from_list([1, 2, 3])))).
28 |
29 | all_put_test_() ->
30 | [?_assertEqual({ok, [4]},
31 | sort_put(
32 | optic:put([optic_sets:all([strict])],
33 | 4,
34 | sets:from_list([1, 2, 3])))),
35 | ?_assertEqual({error, undefined},
36 | optic:put([optic_sets:all([strict])], 4, atom))].
37 |
38 | all_create_test() ->
39 | ?assertEqual({ok, sets:new()},
40 | optic:put([optic_sets:all([strict, create])],
41 | 4,
42 | atom)).
43 |
44 | %%%===================================================================
45 | %%% Internal Functions
46 | %%%===================================================================
47 |
48 | sort_get({ok, Result}) ->
49 | {ok, lists:sort(Result)}.
50 |
51 | sort_put({ok, Result}) ->
52 | {ok, lists:sort(sets:to_list(Result))}.
53 |
--------------------------------------------------------------------------------
/test/test_optic_tuples.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %%% @doc
3 | %%% Tests for src/optic_tuples.erl
4 | %%% @end
5 | %%%-------------------------------------------------------------------
6 | -module(test_optic_tuples).
7 |
8 | -include("include/optic_tuples.hrl").
9 | -include_lib("eunit/include/eunit.hrl").
10 |
11 | -record(test_optic_tuples, {one=1, two=2, three=3}).
12 |
13 | %%%===================================================================
14 | %%% Tests
15 | %%%===================================================================
16 |
17 | all_get_test_() ->
18 | [?_assertEqual({ok, [1, 2, 3]},
19 | optic:get([optic_tuples:all([strict])], {1, 2, 3})),
20 | ?_assertEqual({error, undefined},
21 | optic:get([optic_tuples:all([strict])], atom))].
22 |
23 | all_put_test_() ->
24 | [?_assertEqual({ok, {4, 4, 4}},
25 | optic:put([optic_tuples:all([strict])], 4, {1, 2, 3})),
26 | ?_assertEqual({error, undefined},
27 | optic:put([optic_tuples:all([strict])], 4, atom))].
28 |
29 | all_create_test() ->
30 | ?assertEqual({ok, {}},
31 | optic:put([optic_tuples:all([strict, create])], 4, atom)).
32 |
33 | element_get_test_() ->
34 | [?_assertEqual({ok, [1]},
35 | optic:get([optic_tuples:element(1, [strict])], {1, 2, 3})),
36 | ?_assertEqual({error, undefined},
37 | optic:get([optic_tuples:element(1, [strict])], atom))].
38 |
39 | element_put_test_() ->
40 | [?_assertEqual({ok, {4, 2, 3}},
41 | optic:put([optic_tuples:element(1, [strict])],
42 | 4,
43 | {1, 2, 3})),
44 | ?_assertEqual({error, undefined},
45 | optic:put([optic_tuples:element(1, [strict])],
46 | 4,
47 | atom))].
48 |
49 | element_create_test_() ->
50 | [?_assertEqual({ok, {undefined, 4}},
51 | optic:put([optic_tuples:element(2, [strict,
52 | {create, undefined}])],
53 | 4,
54 | atom)),
55 | ?_assertEqual({ok, {1, undefined, 4}},
56 | optic:put([optic_tuples:element(3, [strict,
57 | {create, undefined}])],
58 | 4,
59 | {1}))].
60 |
61 | field_get_test_() ->
62 | [?_assertEqual({ok, [1]},
63 | optic:get([optic_tuples:field(
64 | test_optic_tuples,
65 | record_info(size, test_optic_tuples),
66 | #test_optic_tuples.one,
67 | [strict])],
68 | #test_optic_tuples{})),
69 | ?_assertEqual({ok, [1]},
70 | optic:get([optic_tuples:field(
71 | ?OPTIC_FIELD(test_optic_tuples, one))],
72 | #test_optic_tuples{})),
73 | ?_assertEqual({error, undefined},
74 | optic:get([optic_tuples:field(
75 | test_optic_tuples,
76 | record_info(size, test_optic_tuples),
77 | #test_optic_tuples.one,
78 | [strict])],
79 | {test_optic_tuples}))].
80 |
81 | field_put_test_() ->
82 | [?_assertEqual({ok, {test_optic_tuples, 4, 2, 3}},
83 | optic:put([optic_tuples:field(
84 | test_optic_tuples,
85 | record_info(size, test_optic_tuples),
86 | #test_optic_tuples.one,
87 | [strict])],
88 | 4,
89 | #test_optic_tuples{})),
90 | ?_assertEqual({ok, {test_optic_tuples, 4, 2, 3}},
91 | optic:put([optic_tuples:field(
92 | ?OPTIC_FIELD(test_optic_tuples, one))],
93 | 4,
94 | #test_optic_tuples{})),
95 | ?_assertEqual({error, undefined},
96 | optic:put([optic_tuples:field(
97 | test_optic_tuples,
98 | record_info(size, test_optic_tuples),
99 | #test_optic_tuples.one,
100 | [strict])],
101 | 4,
102 | {test_optic_tuples}))].
103 |
104 | field_create_test() ->
105 | ?assertEqual({ok, {test_optic_tuples, 4, undefined, undefined}},
106 | optic:put([optic_tuples:field(
107 | test_optic_tuples,
108 | record_info(size, test_optic_tuples),
109 | #test_optic_tuples.one,
110 | [strict, {create, undefined}])],
111 | 4,
112 | {test_optic_tuples})).
113 |
--------------------------------------------------------------------------------