foobara 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/projects/command/src/concerns/reflection.rb +1 -1
- data/projects/command_connectors_http/src/http/response.rb +2 -2
- data/projects/command_connectors_http/src/http.rb +9 -0
- data/projects/manifest/src/foobara/manifest/type.rb +1 -1
- data/projects/manifest/src/foobara/manifest/type_declaration.rb +1 -1
- data/projects/type_declarations/src/type_declaration_handler.rb +1 -1
- data/projects/types/src/type.rb +2 -2
- data/projects/value/src/processor/casting.rb +2 -2
- data/projects/value/src/processor/multi.rb +2 -2
- data/projects/value/src/processor/selection.rb +2 -2
- data/projects/version/src/version.rb +1 -1
- metadata +2 -9
- data/.rspec +0 -5
- data/.rubocop.yml +0 -20
- data/.ruby-version +0 -1
- data/DECISION_LOG.md +0 -220
- data/Guardfile +0 -9
- data/Rakefile +0 -10
- data/concepts.md +0 -153
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 782f9f751e5ade5abc8f593f9f3fb6afe456df2d2a5636554652432ff44722e5
|
4
|
+
data.tar.gz: ce77c639a1a7e5f9c79833610655e65ee6ed5e8051ce77c19ca43bbb58c748eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfce0e9aec6e7b6212ee1bc236e8bca42fba3a380ddce7a2fe75db012f738c3ad13d41a9f8d98438d18252ba92f3a87b90cdb5087d5cfc19006672d6d519db6f
|
7
|
+
data.tar.gz: b2221f7c2920cb7f5978f5ead9e3655a47fe464d6a738445f111e619736d6212f56d97e066d90000934878844c2a6b3937b58366eb086990987fc367b58d1649
|
data/CHANGELOG.md
CHANGED
@@ -60,6 +60,15 @@ module Foobara
|
|
60
60
|
def headers_for(request)
|
61
61
|
response_headers = request.response_headers
|
62
62
|
|
63
|
+
if response_headers.nil? || !response_headers.key?("content-type")
|
64
|
+
if request.command.respond_to?(:serialize_result)
|
65
|
+
# TODO: we should ask the request this not the command.
|
66
|
+
if request.command.serializers.include?(Serializers::JsonSerializer)
|
67
|
+
response_headers = (response_headers || {}).merge("content-type" => "application/json")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
63
72
|
if response_headers
|
64
73
|
static_headers.merge(response_headers)
|
65
74
|
else
|
@@ -94,7 +94,7 @@ module Foobara
|
|
94
94
|
|
95
95
|
def process_value(raw_type_declaration)
|
96
96
|
# TODO: deep_dup this again??
|
97
|
-
super
|
97
|
+
super.tap do |type_outcome|
|
98
98
|
if type_outcome.success?
|
99
99
|
type_outcome.result.raw_declaration_data = raw_type_declaration
|
100
100
|
end
|
data/projects/types/src/type.rb
CHANGED
@@ -35,7 +35,7 @@ module Foobara
|
|
35
35
|
attr_reader :type_symbol
|
36
36
|
|
37
37
|
def initialize(
|
38
|
-
|
38
|
+
*,
|
39
39
|
target_classes:,
|
40
40
|
base_type:,
|
41
41
|
description: nil,
|
@@ -63,7 +63,7 @@ module Foobara
|
|
63
63
|
self.name = name
|
64
64
|
self.target_classes = Util.array(target_classes)
|
65
65
|
|
66
|
-
super(
|
66
|
+
super(*, **opts.merge(processors:, prioritize: false))
|
67
67
|
|
68
68
|
validate_processors!
|
69
69
|
end
|
@@ -39,7 +39,7 @@ module Foobara
|
|
39
39
|
|
40
40
|
attr_accessor :target_classes
|
41
41
|
|
42
|
-
def initialize(
|
42
|
+
def initialize(*, casters:, target_classes: nil)
|
43
43
|
self.target_classes = Util.array(target_classes)
|
44
44
|
|
45
45
|
processors = [
|
@@ -47,7 +47,7 @@ module Foobara
|
|
47
47
|
*casters
|
48
48
|
]
|
49
49
|
|
50
|
-
super(
|
50
|
+
super(*, processors:)
|
51
51
|
end
|
52
52
|
|
53
53
|
def needs_cast?(value)
|
@@ -10,10 +10,10 @@ module Foobara
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
def initialize(
|
13
|
+
def initialize(*, processors: [], prioritize: true)
|
14
14
|
self.prioritize = prioritize
|
15
15
|
self.processors = prioritize ? processors.sort_by(&:priority) : processors
|
16
|
-
super(*
|
16
|
+
super(*)
|
17
17
|
end
|
18
18
|
|
19
19
|
def processor_names
|
@@ -18,9 +18,9 @@ module Foobara
|
|
18
18
|
|
19
19
|
attr_accessor :enforce_unique
|
20
20
|
|
21
|
-
def initialize(
|
21
|
+
def initialize(*, enforce_unique: true, **)
|
22
22
|
self.enforce_unique = enforce_unique
|
23
|
-
super(
|
23
|
+
super(*, **)
|
24
24
|
end
|
25
25
|
|
26
26
|
# TODO: move applies_message usage here from casting processor
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foobara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miles Georgi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: foobara-util
|
@@ -32,17 +32,10 @@ executables: []
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
-
- ".rspec"
|
36
|
-
- ".rubocop.yml"
|
37
|
-
- ".ruby-version"
|
38
35
|
- CHANGELOG.md
|
39
|
-
- DECISION_LOG.md
|
40
|
-
- Guardfile
|
41
36
|
- LICENSE-AGPL.txt
|
42
37
|
- LICENSE.txt
|
43
38
|
- README.md
|
44
|
-
- Rakefile
|
45
|
-
- concepts.md
|
46
39
|
- projects/builtin_types/lib/foobara/builtin_types.rb
|
47
40
|
- projects/builtin_types/src/README.md
|
48
41
|
- projects/builtin_types/src/array/casters/arrayable.rb
|
data/.rspec
DELETED
data/.rubocop.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
AllCops:
|
2
|
-
TargetRubyVersion: 3.2
|
3
|
-
NewCops: enable
|
4
|
-
|
5
|
-
inherit_gem:
|
6
|
-
foobara-rubocop-rules:
|
7
|
-
- rules/*
|
8
|
-
|
9
|
-
Naming/FileName:
|
10
|
-
ExpectMatchingDefinition: true
|
11
|
-
CheckDefinitionPathHierarchy: true
|
12
|
-
Exclude:
|
13
|
-
- spec/lib/**/*
|
14
|
-
- spec/**/*
|
15
|
-
- bin/*
|
16
|
-
CheckDefinitionPathHierarchyRoots:
|
17
|
-
- src
|
18
|
-
- extensions
|
19
|
-
- spec
|
20
|
-
IgnoreExecutableScripts: true
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.2.2
|
data/DECISION_LOG.md
DELETED
@@ -1,220 +0,0 @@
|
|
1
|
-
This document is intended to document the rationale behind certain key decisions
|
2
|
-
|
3
|
-
<!-- TOC -->
|
4
|
-
* [2024-05-30 Dual-license under Apache-2.0 OR MIT](#2024-05-30-dual-license-under-apache-20-or-mit)
|
5
|
-
* [Decision](#decision)
|
6
|
-
* [Rationale](#rationale)
|
7
|
-
* [Why MIT](#why-mit)
|
8
|
-
* [Why Apache-2.0](#why-apache-20)
|
9
|
-
* [Why Apache-2.0 OR MIT](#why-apache-20-or-mit)
|
10
|
-
* [Other licenses that were contenders](#other-licenses-that-were-contenders)
|
11
|
-
* [Other concern about the murky state of generative AI and copyright implications](#other-concern-about-the-murky-state-of-generative-ai-and-copyright-implications)
|
12
|
-
* [[RETRACTED] 2024-05-19 License under user choice of 3 licenses](#retracted-2024-05-19-license-under-user-choice-of-3-licenses)
|
13
|
-
* [Decision](#decision-1)
|
14
|
-
* [Rationale](#rationale-1)
|
15
|
-
* [Why MIT OR Apache 2.0](#why-mit-or-apache-20)
|
16
|
-
* [Why MIT is attractive](#why-mit-is-attractive)
|
17
|
-
* [Why Apache 2.0 is attractive](#why-apache-20-is-attractive)
|
18
|
-
* [Why MIT OR Apache 2.0 is attractive](#why-mit-or-apache-20-is-attractive)
|
19
|
-
* [Why OR MPL 2.0](#why-or-mpl-20)
|
20
|
-
* [why MPL 2.0 is attractive](#why-mpl-20-is-attractive)
|
21
|
-
* [Why OR MPL 2.0, ie, why is MPL 2.0 scary](#why-or-mpl-20-ie-why-is-mpl-20-scary)
|
22
|
-
* [What would have been an ideal license?](#what-would-have-been-an-ideal-license)
|
23
|
-
* [Conclusion](#conclusion)
|
24
|
-
<!-- TOC -->
|
25
|
-
|
26
|
-
# 2024-05-31 Temporarily release under AGPLv3
|
27
|
-
|
28
|
-
## Decision
|
29
|
-
|
30
|
-
Adopting a very restrictive license temporarily
|
31
|
-
|
32
|
-
## Rationale
|
33
|
-
|
34
|
-
Unblocks demos that benefit from use of rubygems while buying time to officially finalize a licensing decision.
|
35
|
-
|
36
|
-
# [TENTATIVE] 2024-05-30 Dual-license under Apache-2.0 OR MIT
|
37
|
-
|
38
|
-
## Decision
|
39
|
-
|
40
|
-
Release gems in the foobara org under Apache-2.0 OR MIT.
|
41
|
-
|
42
|
-
## Rationale
|
43
|
-
|
44
|
-
### Why MIT
|
45
|
-
|
46
|
-
* Typical license of the Ruby ecosystem
|
47
|
-
* High-compatibility with other software licenses.
|
48
|
-
|
49
|
-
### Why Apache-2.0
|
50
|
-
|
51
|
-
* Robust
|
52
|
-
* Includes patent grants
|
53
|
-
|
54
|
-
### Why Apache-2.0 OR MIT
|
55
|
-
|
56
|
-
* Maximizes contexts in which Foobara can unambiguously be used without
|
57
|
-
much overhead or confusion.
|
58
|
-
* Reduces needs to debate less typical licensing options with users
|
59
|
-
or contributors.
|
60
|
-
* Reduces need to relicense later for adoption's sake.
|
61
|
-
* Just Apache-2.0 results in incompatibility with GPLv2
|
62
|
-
* Just MIT does not explicitly extend patent grants.
|
63
|
-
|
64
|
-
A thought... By choosing this combination instead of MPL-2.0, then it's not
|
65
|
-
possible to use Foobara in a GPLv2 app without receiving a patent grant from the
|
66
|
-
MIT license. However, my understanding is that such a user does at least know that
|
67
|
-
all contributors have granted any patents in their contributed code to the Foobara
|
68
|
-
project itself by meeting the requirements of both licenses in order to contribute.
|
69
|
-
|
70
|
-
### Other licenses that were contenders
|
71
|
-
|
72
|
-
* MPL-2.0
|
73
|
-
* Pros:
|
74
|
-
* Robust
|
75
|
-
* Compatible with GPLv2 and includes patent grants, eliminating the need to dual-license
|
76
|
-
* Cons:
|
77
|
-
* Not typical in the Ruby ecosystem and would result in conversations among contributors and users.
|
78
|
-
* Could also potentially impact adoption negatively though I don't think it logically should.
|
79
|
-
* Neutral:
|
80
|
-
* The copyleft aspects of MPL-2.0 seem fair while still being quite permissive. However, likely irrelevant because:
|
81
|
-
* These types of projects are typically used as unmodified libraries distributed by rubygems.
|
82
|
-
* When there is a modification, there's not much incentive not to share those improvements. It is
|
83
|
-
a hassle to manage a private fork and easier to just upstream improvements to avoid
|
84
|
-
that hassle.
|
85
|
-
* Even in the case of a private fork, typically the code winds up being used in some network service
|
86
|
-
and not "distributed" and so the copyleft is irrelevant in these common usage patterns
|
87
|
-
* File-level aspect.
|
88
|
-
* Receiving a copy of the modified code is generally the normal usage pattern since it's
|
89
|
-
an interpreted language. There are some tools for encoding but usually Ruby is interpreted from the source,
|
90
|
-
however, the typical pattern is to receive the code.
|
91
|
-
* Also means static-linking stuff is not relevant
|
92
|
-
* Ruby is so easy to monkey patch. It is very easy to modify a Ruby program without modifying a specific file.
|
93
|
-
Potentially undesirable to go down that path. Not sure. But, regardless, there are many ways to add
|
94
|
-
important code to a code base without disturbing certain files or at least minimally disturb them.
|
95
|
-
And, so, major improvements to code under the MPL can be made without technically triggering the copyleft
|
96
|
-
by leaving the old code in place and hooking new code into it.
|
97
|
-
* Makes it clear what license contributions are under (if using license headers in files.) This is because
|
98
|
-
1) modifications to existing files are MPL-2.0 via terms of the license, regardless of contributor intent.
|
99
|
-
2) new files can be force via the build to have license headers and therefore would express intent
|
100
|
-
by the contributor to license the code as MPL-2.0.
|
101
|
-
|
102
|
-
* Why irrelevant? Because github inbound=outbound convention means if the project is under X license
|
103
|
-
then a contribution is under X license by default.
|
104
|
-
* OSL-3.0
|
105
|
-
* Pros
|
106
|
-
* This was the license I liked best of all the licenses I read. It felt quite fair and robust.
|
107
|
-
* Cons
|
108
|
-
* incompatible with not only GPLv2 but all GPL. So it's really dead-on-arrival.
|
109
|
-
* Is not popular and hasn't been defended in court.
|
110
|
-
* EUPL and CDDL
|
111
|
-
* Based on MPL-1.1 and not compatible with GPLv2
|
112
|
-
* LGPL
|
113
|
-
* Not very concise especially for an interpreted language.
|
114
|
-
* I'm worried about users incorrectly lumping it in with strong copyleft.
|
115
|
-
* I find it interesting that GNU recommends that you don't use LGPL.
|
116
|
-
* I think the philosophical/political views of the license authors on OSS are not really necessary
|
117
|
-
and I'm hesitant to make it seem like it's a position communicated by a community.
|
118
|
-
|
119
|
-
### Other concern about the murky state of generative AI and copyright implications
|
120
|
-
|
121
|
-
I would like similar code generated from AI trained on code from this project, or prompted with code
|
122
|
-
from this project, to be considered a derived work.
|
123
|
-
|
124
|
-
It doesn't seem like any of the existing popular licenses influence whether or not an AI-generated work
|
125
|
-
is considered derived or not.
|
126
|
-
|
127
|
-
# [RETRACTED] 2024-05-19 License under user choice of 3 licenses
|
128
|
-
|
129
|
-
## Decision
|
130
|
-
|
131
|
-
RETRACTED: kept in the history but should relocate these thoughts to some other resource.
|
132
|
-
|
133
|
-
Release foobara gem (this repository) under the user's preference of
|
134
|
-
3 different licenses: `MIT OR Apache 2.0 OR MPL 2.0` and come up with a shorter alias for this license.
|
135
|
-
|
136
|
-
## Rationale
|
137
|
-
|
138
|
-
### Why MIT OR Apache 2.0
|
139
|
-
|
140
|
-
#### Why MIT is attractive
|
141
|
-
|
142
|
-
MIT is attractive, aside from the obvious (permissible, simple), because this license
|
143
|
-
is the typical license used in the Ruby community. Adoption would be as known-to-be-simple as possible under
|
144
|
-
this license in this ecosystem.
|
145
|
-
|
146
|
-
#### Why Apache 2.0 is attractive
|
147
|
-
|
148
|
-
Apache 2.0 is attractive due to its robustness and extending patent permissions to users.
|
149
|
-
|
150
|
-
#### Why MIT OR Apache 2.0 is attractive
|
151
|
-
|
152
|
-
Dual-licensing under both allows the end-user to operate under either as-needed.
|
153
|
-
|
154
|
-
The Rust community dual licenses under these two suggesting that a community can function under such
|
155
|
-
a licensing scheme.
|
156
|
-
|
157
|
-
Also, Bootstrap, in 2012, relicensed from Apache 2.0 to MIT so that GPLv2 projects could use Bootstrap.
|
158
|
-
Dual licensing would have also been a solution but the point here is future-proofing unexpected pressure to
|
159
|
-
relicense for adoption-sake.
|
160
|
-
|
161
|
-
### Why OR MPL 2.0
|
162
|
-
|
163
|
-
#### why MPL 2.0 is attractive
|
164
|
-
|
165
|
-
MPL 2.0 seems to me (I am not an expert on this and far from it) after some research to be a robust license
|
166
|
-
that seems to give nearly as much encouragement to give contributors back improvements to their
|
167
|
-
original efforts without sacrificing much, if any, practical permissiveness.
|
168
|
-
|
169
|
-
#### Why OR MPL 2.0, ie, why is MPL 2.0 scary
|
170
|
-
|
171
|
-
It seems like there would be no serious practical burden imposed on users by the MPL 2.0 license. But I'm not
|
172
|
-
100% certain of that without expert confirmation. And so, if users are also uncertain, that might hurt adoption
|
173
|
-
even if in actuality the license is not a hassle to users in any meaningful way.
|
174
|
-
|
175
|
-
What I mean by this is: if I have an MIT-licensed project, or a proprietary project, and I add a MPL-2.0 only gem
|
176
|
-
to my .gemspec, is there any administrative burden imposed? It seems like "no" but again I am not an expert.
|
177
|
-
If the answer is "no" but unclear to the user, that might still hurt adoption. To that extent, if confused with GPL
|
178
|
-
style licenses, it might be ruled out by some organizations even if incorrectly so.
|
179
|
-
|
180
|
-
However, making it OR MIT OR Apache 2.0 allows the user to just operate as if the project were licensed in
|
181
|
-
the way most convenient to the user among those options, making adoption, I assume, at least as easy as MIT alone.
|
182
|
-
|
183
|
-
But the real suspected benefit is this seems like it would allow MPL 2.0 to be the preferred license in the future
|
184
|
-
without needing to seek relicense permission from contributors, nor CLAs to avoid seeking relicense permission.
|
185
|
-
It is, in essence, a solution to punt and get back to coding for now and revisit with more real-world information
|
186
|
-
later.
|
187
|
-
|
188
|
-
### What would have been an ideal license?
|
189
|
-
|
190
|
-
Hard to say without being an expert on licenses and user behavior but, at this time, my best (admittedly uninformed)
|
191
|
-
guess would be to ideally use only one license, similar to MPL 2.0, but:
|
192
|
-
|
193
|
-
1) without the file-level/static stuff as it is likely irrelevant for a gem like Foobara.
|
194
|
-
2) with a network-exposure-is-distribution clause like AGPL 3.0, or really anything to maximize an
|
195
|
-
"if you improve it and make use of those improvements, then share the improvements" vibe, which,
|
196
|
-
with github and forks, seems like a trivial requirement to satisfy.
|
197
|
-
3) if possible, a clause stating that code generated from Foobara code as
|
198
|
-
training data or prompt data to an AI system constitutes a derived work.
|
199
|
-
|
200
|
-
Without expertise and given the point in history where I'm making this decision, I can't really draft
|
201
|
-
such a license and even if I could that seems like it could be a bad strategy regardless (aka license proliferation)
|
202
|
-
|
203
|
-
NOTE: if you happen to know an easy way for me to access expertise for clarity on these issues, please let me know.
|
204
|
-
I'd be happy to pay for a short consult with a professional (ie lawyer who specializes in open-source licensing.)
|
205
|
-
|
206
|
-
## Conclusion
|
207
|
-
|
208
|
-
License under MIT OR Apache 2.0 OR MPL 2.0 for now to:
|
209
|
-
|
210
|
-
1) guarantee seamless fit into Ruby ecosystem (MIT)
|
211
|
-
2) extend patent-granting in case somebody wants that (Apache 2.0/MPL 2.0)
|
212
|
-
3) allow future relicensing under MPL 2.0 without CLAs or non-trivial-contributor-roundup if it turns out that MPL 2.0
|
213
|
-
would have been a good choice once more is understood about the adoption-impact of having chosen that license.
|
214
|
-
4) stop thinking about licensing and get back to hackin'
|
215
|
-
|
216
|
-
To be clear, we are punting for now. At some point, we should choose either:
|
217
|
-
|
218
|
-
1) MPL 2.0
|
219
|
-
2) MIT OR Apache 2.0 (works for Rust community... seems there's no need to decide between these two)
|
220
|
-
3) Some other better-fitting license (would require permission from non-trivial contributors)
|
data/Guardfile
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
guard :rspec, all_after_pass: true, all_on_start: true, cmd: "bundle exec rspec", failed_mode: :focus do
|
2
|
-
watch(%r{^spec/(.+)_spec\.rb$})
|
3
|
-
watch(%r{^src/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
|
-
watch(%r{^src/foobara/command/concerns/(.+)\.rb$}) { |_m| "spec/foobara/command_spec.rb" }
|
5
|
-
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
6
|
-
watch(%r{^spec/spec_helper.rb$}) { "spec/" }
|
7
|
-
watch(%r{^src/commands.rb$/}) { "spec/" }
|
8
|
-
watch(%r{^projects/([^/]+)/src/(.+)\.rb$}) { |m| "spec/foobara/#{m[1]}/#{m[2]}_spec.rb" }
|
9
|
-
end
|
data/Rakefile
DELETED
data/concepts.md
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
<!-- TOC -->
|
2
|
-
|
3
|
-
* [Command](#command)
|
4
|
-
* [Type < Value::Processor](#type--valueprocessor)
|
5
|
-
* [type declaration value](#type-declaration-value)
|
6
|
-
* [Type reference](#type-reference)
|
7
|
-
* [Domain](#domain)
|
8
|
-
* [Organization](#organization)
|
9
|
-
* [Domain mapper](#domain-mapper)
|
10
|
-
* [Value::Processor](#valueprocessor)
|
11
|
-
* [Value::Caster < Value::Processor](#valuecaster--valueprocessor)
|
12
|
-
* [Value::Validator < Value::Processor](#valuevalidator--valueprocessor)
|
13
|
-
* [Value::Transformer < Value::Processor](#valuetransformer--valueprocessor)
|
14
|
-
* [Desugarizer < Value::Transformer](#desugarizer--valuetransformer)
|
15
|
-
* [TypeDeclarationValidator < Value::Validator](#typedeclarationvalidator--valuevalidator)
|
16
|
-
* [in general:](#in-general)
|
17
|
-
* [types and type declarations:](#types-and-type-declarations)
|
18
|
-
|
19
|
-
<!-- TOC -->
|
20
|
-
|
21
|
-
These are notes about some things conceptual.
|
22
|
-
|
23
|
-
# Command
|
24
|
-
|
25
|
-
* A command is an encapsulation of a high-level business operation and is intended to be the public
|
26
|
-
interface of a system or subsystem.
|
27
|
-
|
28
|
-
# Type < Value::Processor
|
29
|
-
|
30
|
-
A type is an instance of the Types::Type class.
|
31
|
-
|
32
|
-
It (the instance) is a namespace.
|
33
|
-
|
34
|
-
It is a Value::Processor
|
35
|
-
|
36
|
-
* reflection
|
37
|
-
* can give a type declaration value (formal or informal/sugary or strict) for this type
|
38
|
-
* can give the list of possible errors that could result from processing a value of this type
|
39
|
-
and the types for their context schemas
|
40
|
-
* can answer what value processors are supported for values of this type
|
41
|
-
* can answer which value processors are automatically applied for values of this type
|
42
|
-
* can serve as a base type for another type
|
43
|
-
* can process a value of this type
|
44
|
-
* can answer if a value needs to be cast
|
45
|
-
* can answer if a value can be cast
|
46
|
-
* can cast a value into an value of this type
|
47
|
-
* can transform a value of this type
|
48
|
-
* can validate a value of this type
|
49
|
-
* processor registry operations
|
50
|
-
* can register a supported value processor
|
51
|
-
* can register a value caster
|
52
|
-
|
53
|
-
# type declaration value
|
54
|
-
|
55
|
-
* Something that defines/declares a type in a declarative fashion.
|
56
|
-
* Can have a sugary form for human expression/readability/writability
|
57
|
-
* Is easily serializable for cross-system metaprogramming
|
58
|
-
* example:
|
59
|
-
```ruby
|
60
|
-
{
|
61
|
-
foo: :integer,
|
62
|
-
bar: [:integer, :optional, :allow_blank, min: 1]
|
63
|
-
}
|
64
|
-
```
|
65
|
-
* In this example, we are using a sugary declaration to specify a new type of
|
66
|
-
attributes type that can represent a value like `{ foo: -20, bar: 10 }`
|
67
|
-
|
68
|
-
# Type reference
|
69
|
-
|
70
|
-
* References a "registered" type. A registered type has a type symbol and belongs to a domain.
|
71
|
-
* An unresolved type reference doesn't have to be absolute and is looked up in the current
|
72
|
-
Foobara namespace.
|
73
|
-
* A resolved type is absolute.
|
74
|
-
* A type reference can be used as a type declaration.
|
75
|
-
|
76
|
-
# Domain
|
77
|
-
|
78
|
-
* A namespace for Commands and Types
|
79
|
-
* can depend on other domains in a unidirectional way
|
80
|
-
|
81
|
-
# Organization
|
82
|
-
|
83
|
-
* namespace for collecting domains
|
84
|
-
|
85
|
-
# Domain mapper
|
86
|
-
|
87
|
-
* Translates models (or types or commands inputs/results) to models (or types or command inputs/results) in
|
88
|
-
another domain.
|
89
|
-
|
90
|
-
# Value::Processor
|
91
|
-
|
92
|
-
* Has a process_value method that receives a value and returns an Outcome
|
93
|
-
* Can have an applicable?(value) method
|
94
|
-
* Answers what errors are possible
|
95
|
-
* Including the type of their context
|
96
|
-
|
97
|
-
## Value::Caster < Value::Processor
|
98
|
-
|
99
|
-
* gives #cast instead of #transform but same idea, takes value returns value
|
100
|
-
* like ValueProcessor, never gives errors
|
101
|
-
* only one value caster per type should be #applicable? for a given value.
|
102
|
-
* Therefore doesn't have to play nicely with other Casters, unlike Transformers/Validators
|
103
|
-
|
104
|
-
## Value::Validator < Value::Processor
|
105
|
-
|
106
|
-
* gives #validation_errors that takes value and returns errors
|
107
|
-
* never gives new value
|
108
|
-
|
109
|
-
## Value::Transformer < Value::Processor
|
110
|
-
|
111
|
-
* gives #transfomer that takes value and returns value
|
112
|
-
* never gives errors
|
113
|
-
|
114
|
-
## Desugarizer < Value::Transformer
|
115
|
-
|
116
|
-
* takes sugary type declaration and returns strict type declaration
|
117
|
-
|
118
|
-
## TypeDeclarationValidator < Value::Validator
|
119
|
-
|
120
|
-
* Validates type declarations
|
121
|
-
|
122
|
-
A way to think about the interfaces/concepts involved here, if helpful:
|
123
|
-
|
124
|
-
### in general:
|
125
|
-
|
126
|
-
* Processor, Multi, Selection, Pipeline: value -> outcome
|
127
|
-
* Multi < Processor: value -> outcome
|
128
|
-
* Selection < Multi (chooses 1 processor among many to run): value -> outcome
|
129
|
-
* Pipeline < Multi (chains a collection of processors together): value -> outcome
|
130
|
-
* Processor, Multi, Selection, Pipeline: value -> outcome
|
131
|
-
* Transformer: value -> value
|
132
|
-
* Validator: value -> error[]
|
133
|
-
|
134
|
-
Maybe not helpful, but, you could think of Processor/Multi/Selection/Pipeline as monads
|
135
|
-
and Validator and Transformer as monads but with convenience methods that make assumptions
|
136
|
-
about the context (transformer assumes there are no errors and validator assumes
|
137
|
-
no transformation of the value.)
|
138
|
-
|
139
|
-
### types and type declarations:
|
140
|
-
|
141
|
-
* TypeDeclarationHandler: type declaration -> Type instance
|
142
|
-
* TypeDeclarationHandlerRegistry: type declaration -> outcome<TypeDeclarationHandler>
|
143
|
-
* Desugarizer: type declaration -> strict(er) type declaration
|
144
|
-
* TypeDeclarationValidator: strict type declaration -> error[]
|
145
|
-
* Type instance: value -> outcome
|
146
|
-
* Type casting (is a Value::Pipeline of casters): value -> value
|
147
|
-
* Caster: value -> value
|
148
|
-
* Type transformers: value -> value
|
149
|
-
* Type validators: value -> error[]
|
150
|
-
* Type processors: value -> outcome
|
151
|
-
* Supported type processors: value -> outcome
|
152
|
-
* Supported type transformers: value -> value
|
153
|
-
* Supported type validators: value -> error[]
|