enotype 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +14 -0
- data/lib/enotype.rb +1 -0
- data/lib/enotype/de.rb +103 -0
- data/lib/enotype/en.rb +103 -0
- data/lib/enotype/es.rb +103 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 49b45ee141f7108c88785143cbae350f76dee9dbb6d5dd1acbce7972bc3bbfe6
|
4
|
+
data.tar.gz: 5e3f2de9a97da96a79757a56d2c3be830b3f3ccec01c7392fd437a4bf26fdad6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8cc784fcf21d0d73ade3cd036288b953d40f32fe4a8394cbfb92f10610c052b10fa9ce2997d4237b97e9fec9cf09751bf0ace0464851dab3cd0a634bda24d362
|
7
|
+
data.tar.gz: 57d00f2f5c740134ccfbea7b125ab0ea335795bb0d0b2f9b9e200f2bb60d34494abc11feda7c0caeedf9b23ba4dd37f47faf4e5487d11dd4ffa7ea54e6a2da08
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 Simon Repp
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# enotype
|
2
|
+
|
3
|
+
**A cross-language standard library for types.**
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
require 'enotype'
|
7
|
+
|
8
|
+
Enotype::color('#fff') # returns '#fff'
|
9
|
+
Enotype::color('#xyz') # raises 'A color is required, for instance '#B6D918', '#fff' or '#01b'.'
|
10
|
+
```
|
11
|
+
|
12
|
+
enotype is a collection of minimalist pure functions that validate and convert type-unsafe `string` representations into type-safe, native types.
|
13
|
+
|
14
|
+
It is the standard type library for the [eno notation language](https://eno-lang.org) but can be utilized in a multitude of other contexts as well.
|
data/lib/enotype.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'enotype/en'
|
data/lib/enotype/de.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
COLOR_REGEXP = /^\s*#[0-9a-f]{3}([0-9a-f]{3})?\s*$/i
|
4
|
+
DATE_REGEXP = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/
|
5
|
+
DATETIME_REGEXP = /^\s*(\d{4})(?:-(\d\d)(?:-(\d\d)(?:T(\d\d):(\d\d)(?::(\d\d)(?:\.(\d+))?)?(?:(Z)|([+\-])(\d\d):(\d\d)))?)?)?\s*$/
|
6
|
+
EMAIL_REGEXP = /^\s*[^@\s]+@[^@\s]+\.[^@\s]+\s*$/
|
7
|
+
FLOAT_REGEXP = /^\s*-?\d+(\.\d+)?\s*$/
|
8
|
+
INTEGER_REGEXP = /^\s*-?\d+\s*$/
|
9
|
+
LAT_LNG_REGEXP = /^\s*(-?\d{1,3}(?:\.\d+)?)\s*,\s*(-?\d{1,3}(?:\.\d+)?)\s*$/
|
10
|
+
URL_REGEXP = /^\s*https?:\/\/[^\s.]+\.\S+\s*$/
|
11
|
+
|
12
|
+
module Enotype
|
13
|
+
def self.boolean(value)
|
14
|
+
lower = value.strip.downcase
|
15
|
+
|
16
|
+
return true if lower == 'true'
|
17
|
+
return false if lower == 'false'
|
18
|
+
return true if lower == 'yes'
|
19
|
+
return false if lower == 'no'
|
20
|
+
|
21
|
+
raise 'Ein boolescher Wert ist erforderlich - erlaubte Werte sind \'true\', \'false\', \'yes\' und \'no\'.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.color(value)
|
25
|
+
raise 'Eine Farbe ist erforderlich, zum Beispiel \'#B6D918\', \'#fff\' oder \'#01b\'.' unless value.match(COLOR_REGEXP)
|
26
|
+
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.comma_separated(value)
|
31
|
+
value.split(',', -1).map { |item| item.strip }
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.date(value)
|
35
|
+
match = value.match(DATE_REGEXP)
|
36
|
+
|
37
|
+
raise 'Ein valides Datum ist erforderlich, zum Beispiel \'1993-11-18\'.' unless match
|
38
|
+
|
39
|
+
year = match[1].to_i
|
40
|
+
month = match[2].to_i
|
41
|
+
day = match[3].to_i
|
42
|
+
|
43
|
+
Time.utc(year, month, day)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.datetime(value)
|
47
|
+
match = value.match(DATETIME_REGEXP)
|
48
|
+
|
49
|
+
raise 'Ein valides Datum oder Datum und Zeit sind erforderlich, zum Beispiel \'1961-01-22\' oder \'1989-11-09T19:17Z\' (siehe https://www.w3.org/TR/NOTE-datetime).' unless match
|
50
|
+
|
51
|
+
year = match[1].to_i
|
52
|
+
month = match[2] ? match[2].to_i : 1
|
53
|
+
day = match[3] ? match[3].to_i : 1
|
54
|
+
hour = match[4] ? match[4].to_i : 0
|
55
|
+
minute = match[5] ? match[5].to_i : 0
|
56
|
+
second = match[6] ? match[6].to_i : 0
|
57
|
+
fraction = match[7] ? "0.#{match[7]}".to_f : 0
|
58
|
+
zulu = match[8]
|
59
|
+
offset = zulu ? '+00:00' : "#{match[9] || '+'}#{match[10] || '00'}:#{match[11] || '00'}"
|
60
|
+
|
61
|
+
Time.new(year, month, day, hour, minute, second + fraction, offset)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.email(value)
|
65
|
+
raise 'Eine valide Email Adresse ist erforderlich, zum Beispiel \'jane.doe@eno-lang.org\'.' unless value.match(EMAIL_REGEXP)
|
66
|
+
|
67
|
+
value
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.float(value)
|
71
|
+
raise 'Eine Dezimalzahl ist erforderlich, zum Beispiel \'13.0\', \'-9.159\' oder \'42\'.' unless value.match(FLOAT_REGEXP)
|
72
|
+
|
73
|
+
value.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.integer(value)
|
77
|
+
raise 'Eine Ganzzahl ist erforderlich, zum Beispiel \'42\' oder \'-21\'.' unless value.match(INTEGER_REGEXP)
|
78
|
+
|
79
|
+
value.to_i
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.json(value)
|
83
|
+
begin
|
84
|
+
JSON.parse(value)
|
85
|
+
rescue => err
|
86
|
+
raise "Valides JSON ist erforderlich - die Meldung des Parsers war:\n#{err.message}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.lat_lng(value)
|
91
|
+
match = LAT_LNG_REGEXP.match(value)
|
92
|
+
|
93
|
+
raise 'Ein valides Breiten-/Längengrad Koordinatenpaar ist erforderlich, zum Beispiel \'48.2093723, 16.356099\'.' unless match
|
94
|
+
|
95
|
+
{ lat: match[1].to_f, lng: match[2].to_f }
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.url(value)
|
99
|
+
raise 'Eine valide URL ist erforderlich, zum Beispiel \'https://eno-lang.org\'.' unless value.match(URL_REGEXP)
|
100
|
+
|
101
|
+
value
|
102
|
+
end
|
103
|
+
end
|
data/lib/enotype/en.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
COLOR_REGEXP = /^\s*#[0-9a-f]{3}([0-9a-f]{3})?\s*$/i
|
4
|
+
DATE_REGEXP = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/
|
5
|
+
DATETIME_REGEXP = /^\s*(\d{4})(?:-(\d\d)(?:-(\d\d)(?:T(\d\d):(\d\d)(?::(\d\d)(?:\.(\d+))?)?(?:(Z)|([+\-])(\d\d):(\d\d)))?)?)?\s*$/
|
6
|
+
EMAIL_REGEXP = /^\s*[^@\s]+@[^@\s]+\.[^@\s]+\s*$/
|
7
|
+
FLOAT_REGEXP = /^\s*-?\d+(\.\d+)?\s*$/
|
8
|
+
INTEGER_REGEXP = /^\s*-?\d+\s*$/
|
9
|
+
LAT_LNG_REGEXP = /^\s*(-?\d{1,3}(?:\.\d+)?)\s*,\s*(-?\d{1,3}(?:\.\d+)?)\s*$/
|
10
|
+
URL_REGEXP = /^\s*https?:\/\/[^\s.]+\.\S+\s*$/
|
11
|
+
|
12
|
+
module Enotype
|
13
|
+
def self.boolean(value)
|
14
|
+
lower = value.strip.downcase
|
15
|
+
|
16
|
+
return true if lower == 'true'
|
17
|
+
return false if lower == 'false'
|
18
|
+
return true if lower == 'yes'
|
19
|
+
return false if lower == 'no'
|
20
|
+
|
21
|
+
raise 'A boolean is required - allowed values are \'true\', \'false\', \'yes\' and \'no\'.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.color(value)
|
25
|
+
raise 'A color is required, for instance \'#B6D918\', \'#fff\' or \'#01b\'.' unless value.match(COLOR_REGEXP)
|
26
|
+
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.comma_separated(value)
|
31
|
+
value.split(',', -1).map { |item| item.strip }
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.date(value)
|
35
|
+
match = value.match(DATE_REGEXP)
|
36
|
+
|
37
|
+
raise 'A valid date is required, for instance \'1993-11-18\'.' unless match
|
38
|
+
|
39
|
+
year = match[1].to_i
|
40
|
+
month = match[2].to_i
|
41
|
+
day = match[3].to_i
|
42
|
+
|
43
|
+
Time.utc(year, month, day)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.datetime(value)
|
47
|
+
match = value.match(DATETIME_REGEXP)
|
48
|
+
|
49
|
+
raise 'A valid date or date and time are required, for instance \'1961-01-22\' or \'1989-11-09T19:17Z\' (see https://www.w3.org/TR/NOTE-datetime).' unless match
|
50
|
+
|
51
|
+
year = match[1].to_i
|
52
|
+
month = match[2] ? match[2].to_i : 1
|
53
|
+
day = match[3] ? match[3].to_i : 1
|
54
|
+
hour = match[4] ? match[4].to_i : 0
|
55
|
+
minute = match[5] ? match[5].to_i : 0
|
56
|
+
second = match[6] ? match[6].to_i : 0
|
57
|
+
fraction = match[7] ? "0.#{match[7]}".to_f : 0
|
58
|
+
zulu = match[8]
|
59
|
+
offset = zulu ? '+00:00' : "#{match[9] || '+'}#{match[10] || '00'}:#{match[11] || '00'}"
|
60
|
+
|
61
|
+
Time.new(year, month, day, hour, minute, second + fraction, offset)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.email(value)
|
65
|
+
raise 'A valid email address is required, for instance \'jane.doe@eno-lang.org\'.' unless value.match(EMAIL_REGEXP)
|
66
|
+
|
67
|
+
value
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.float(value)
|
71
|
+
raise 'A decimal number is required, for instance \'13.0\', \'-9.159\' or \'42\'.' unless value.match(FLOAT_REGEXP)
|
72
|
+
|
73
|
+
value.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.integer(value)
|
77
|
+
raise 'An integer is required, for instance \'42\' or \'-21\'.' unless value.match(INTEGER_REGEXP)
|
78
|
+
|
79
|
+
value.to_i
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.json(value)
|
83
|
+
begin
|
84
|
+
JSON.parse(value)
|
85
|
+
rescue => err
|
86
|
+
raise "Valid JSON is required - the parser returned:\n#{err.message}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.lat_lng(value)
|
91
|
+
match = LAT_LNG_REGEXP.match(value)
|
92
|
+
|
93
|
+
raise 'A valid latitude/longitude coordinate pair is required, for instance \'48.2093723, 16.356099\'.' unless match
|
94
|
+
|
95
|
+
{ lat: match[1].to_f, lng: match[2].to_f }
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.url(value)
|
99
|
+
raise 'A valid URL is required, for instance \'https://eno-lang.org\'.' unless value.match(URL_REGEXP)
|
100
|
+
|
101
|
+
value
|
102
|
+
end
|
103
|
+
end
|
data/lib/enotype/es.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
COLOR_REGEXP = /^\s*#[0-9a-f]{3}([0-9a-f]{3})?\s*$/i
|
4
|
+
DATE_REGEXP = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/
|
5
|
+
DATETIME_REGEXP = /^\s*(\d{4})(?:-(\d\d)(?:-(\d\d)(?:T(\d\d):(\d\d)(?::(\d\d)(?:\.(\d+))?)?(?:(Z)|([+\-])(\d\d):(\d\d)))?)?)?\s*$/
|
6
|
+
EMAIL_REGEXP = /^\s*[^@\s]+@[^@\s]+\.[^@\s]+\s*$/
|
7
|
+
FLOAT_REGEXP = /^\s*-?\d+(\.\d+)?\s*$/
|
8
|
+
INTEGER_REGEXP = /^\s*-?\d+\s*$/
|
9
|
+
LAT_LNG_REGEXP = /^\s*(-?\d{1,3}(?:\.\d+)?)\s*,\s*(-?\d{1,3}(?:\.\d+)?)\s*$/
|
10
|
+
URL_REGEXP = /^\s*https?:\/\/[^\s.]+\.\S+\s*$/
|
11
|
+
|
12
|
+
module Enotype
|
13
|
+
def self.boolean(value)
|
14
|
+
lower = value.strip.downcase
|
15
|
+
|
16
|
+
return true if lower == 'true'
|
17
|
+
return false if lower == 'false'
|
18
|
+
return true if lower == 'yes'
|
19
|
+
return false if lower == 'no'
|
20
|
+
|
21
|
+
raise 'Se requiere un valor booleano - valores permitidos son \'true\', \'false\', \'yes\' y \'no\'.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.color(value)
|
25
|
+
raise 'Se requiere un color, por ejemplo \'#B6D918\', \'#fff\' o \'#01b\'.' unless value.match(COLOR_REGEXP)
|
26
|
+
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.comma_separated(value)
|
31
|
+
value.split(',', -1).map { |item| item.strip }
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.date(value)
|
35
|
+
match = value.match(DATE_REGEXP)
|
36
|
+
|
37
|
+
raise 'Se requiere una fecha valida, por ejemplo \'1993-11-18\'' unless match
|
38
|
+
|
39
|
+
year = match[1].to_i
|
40
|
+
month = match[2].to_i
|
41
|
+
day = match[3].to_i
|
42
|
+
|
43
|
+
Time.utc(year, month, day)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.datetime(value)
|
47
|
+
match = value.match(DATETIME_REGEXP)
|
48
|
+
|
49
|
+
raise 'Se requiere una valida fecha o fecha y hora, por ejemplo \'1961-01-22\' o \'1989-11-09T19:17Z\' (vea https://www.w3.org/TR/NOTE-datetime).' unless match
|
50
|
+
|
51
|
+
year = match[1].to_i
|
52
|
+
month = match[2] ? match[2].to_i : 1
|
53
|
+
day = match[3] ? match[3].to_i : 1
|
54
|
+
hour = match[4] ? match[4].to_i : 0
|
55
|
+
minute = match[5] ? match[5].to_i : 0
|
56
|
+
second = match[6] ? match[6].to_i : 0
|
57
|
+
fraction = match[7] ? "0.#{match[7]}".to_f : 0
|
58
|
+
zulu = match[8]
|
59
|
+
offset = zulu ? '+00:00' : "#{match[9] || '+'}#{match[10] || '00'}:#{match[11] || '00'}"
|
60
|
+
|
61
|
+
Time.new(year, month, day, hour, minute, second + fraction, offset)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.email(value)
|
65
|
+
raise 'Se requiere una dirección electrónica valida, por ejemplo \'jane.doe@eno-lang.org\'.' unless value.match(EMAIL_REGEXP)
|
66
|
+
|
67
|
+
value
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.float(value)
|
71
|
+
raise 'Se requiere un número decimal, por ejemplo \'13.0\', \'-9.159\' o \'42\'.' unless value.match(FLOAT_REGEXP)
|
72
|
+
|
73
|
+
value.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.integer(value)
|
77
|
+
raise 'Se requiere un número entero, por ejemplo \'42\' o \'-21\'.' unless value.match(INTEGER_REGEXP)
|
78
|
+
|
79
|
+
value.to_i
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.json(value)
|
83
|
+
begin
|
84
|
+
JSON.parse(value)
|
85
|
+
rescue => err
|
86
|
+
raise "Se requiere JSON valido - el mensaje del parser fue:\n#{err.message}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.lat_lng(value)
|
91
|
+
match = LAT_LNG_REGEXP.match(value)
|
92
|
+
|
93
|
+
raise 'Se requiere una pareja de coordenadas latitud/longitud valida, por ejemplo \'48.2093723, 16.356099\'' unless match
|
94
|
+
|
95
|
+
{ lat: match[1].to_f, lng: match[2].to_f }
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.url(value)
|
99
|
+
raise 'Se requiere un URL valido, por ejemplo \'https://eno-lang.org\'.' unless value.match(URL_REGEXP)
|
100
|
+
|
101
|
+
value
|
102
|
+
end
|
103
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enotype
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Simon Repp
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.8'
|
27
|
+
description: enotype is a collection of minimalist pure functions that validate and
|
28
|
+
convert type-unsafe string representations into type-safe, native types.
|
29
|
+
email: simon@fdpl.io
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE.txt
|
35
|
+
- README.md
|
36
|
+
- lib/enotype.rb
|
37
|
+
- lib/enotype/de.rb
|
38
|
+
- lib/enotype/en.rb
|
39
|
+
- lib/enotype/es.rb
|
40
|
+
homepage: https://eno-lang.org/
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.3.0
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.7.8
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: A cross-language standard library for types
|
64
|
+
test_files: []
|