enotype 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
         
     |