cool_id 0.1.0 → 0.1.2

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cool_id/version.rb +1 -1
  3. data/lib/cool_id.rb +93 -14
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e57670575a5ab4ca42bdd225ada7b79aad7ff9bbd5ad9ffd72374cd121bf07
4
- data.tar.gz: 02e56f84df9d458da1e7e93dc7ec8ff5bcfb33fdfd399f58fed40b36cd3995ea
3
+ metadata.gz: e34a657a23c3321adf021f9ab101a6cee1f792a3e8b71c11702663dd92ac6883
4
+ data.tar.gz: f364193fe7ec136a8a436032a5de7b16a7db6b32b4901baa72f3eaa4a39267ea
5
5
  SHA512:
6
- metadata.gz: 91c18c5d5a6be61f1f6ece0ddb1b7625c3d0c4675ec690550785221244a889b808c8032b22b79e8987d46cf5e5435f3f11b332298edc57a149348bf6f6f312f4
7
- data.tar.gz: 138806308d00d10e64387254bfaef9650fbfe48e89d2201d301b385f26b9713120ee86ec8b0ed750e138accfa30ae1dfd7f15d3604b1b56275d5d3e40955f825
6
+ metadata.gz: 54f60190090f171c8c9f3df697378ad65fb9224551b208fadaddf0b4e2da37818126cbb52127a79e32ede2156f9e59cfe81eedfd20a7bd50dcac83371056806e
7
+ data.tar.gz: eb277e15108b217785785803a854d6f88405d2e9fd2b8bcf84583890fbb1fb8a48b2392c2b2a9aa20567d547f92fd5ccd2bce946636acc8ccb1e7781d8985e87
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CoolId
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/cool_id.rb CHANGED
@@ -3,35 +3,106 @@
3
3
  require_relative "cool_id/version"
4
4
  require "nanoid"
5
5
  require "active_support/concern"
6
- require "active_record"
7
6
 
8
7
  module CoolId
9
8
  class Error < StandardError; end
10
9
 
11
- # defaults copped from
12
- # https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
13
- DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
14
10
  DEFAULT_SEPARATOR = "_"
11
+ DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
15
12
  DEFAULT_LENGTH = 12
16
13
 
17
- def self.generate_id(prefix: "", separator: DEFAULT_SEPARATOR, length: DEFAULT_LENGTH, alphabet: DEFAULT_ALPHABET)
18
- id = Nanoid.generate(size: length, alphabet: alphabet)
19
- [prefix, id].reject(&:empty?).join(separator)
14
+ Id = Struct.new(:key, :prefix, :id, :model_class)
15
+
16
+ class << self
17
+ attr_accessor :separator, :alphabet, :length
18
+
19
+ def configure
20
+ yield self
21
+ end
22
+
23
+ def reset_configuration
24
+ self.separator = DEFAULT_SEPARATOR
25
+ self.alphabet = DEFAULT_ALPHABET
26
+ self.length = DEFAULT_LENGTH
27
+ end
28
+
29
+ def registry
30
+ @registry ||= Registry.new
31
+ end
32
+
33
+ def generate_id(config)
34
+ alphabet = config.alphabet || @alphabet
35
+ length = config.length || @length
36
+ id = Nanoid.generate(size: length, alphabet: alphabet)
37
+
38
+ "#{config.prefix}#{separator}#{id}"
39
+ end
40
+ end
41
+
42
+ # defaults based on https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
43
+ self.separator = DEFAULT_SEPARATOR
44
+ self.alphabet = DEFAULT_ALPHABET
45
+ self.length = DEFAULT_LENGTH
46
+
47
+ class Registry
48
+ def initialize
49
+ @registry = {}
50
+ end
51
+
52
+ def register(prefix, model_class)
53
+ @registry[prefix] = model_class
54
+ end
55
+
56
+ def locate(id)
57
+ parsed = parse(id)
58
+ parsed&.model_class&.find_by(id: id)
59
+ end
60
+
61
+ def parse(id)
62
+ prefix, key = id.split(CoolId.separator, 2)
63
+ model_class = @registry[prefix]
64
+ return nil unless model_class
65
+ Id.new(key, prefix, id, model_class)
66
+ end
67
+ end
68
+
69
+ class Config
70
+ attr_reader :prefix, :length, :alphabet
71
+
72
+ def initialize(prefix:, length: nil, alphabet: nil)
73
+ @length = length
74
+ @prefix = validate_prefix(prefix)
75
+ @alphabet = validate_alphabet(alphabet)
76
+ end
77
+
78
+ private
79
+
80
+ def validate_prefix(value)
81
+ raise ArgumentError, "Prefix cannot be nil" if value.nil?
82
+ raise ArgumentError, "Prefix cannot consist only of whitespace" if value.strip.empty?
83
+ value
84
+ end
85
+
86
+ def validate_alphabet(value)
87
+ return nil if value.nil?
88
+ raise ArgumentError, "Alphabet cannot include the separator '#{CoolId.separator}'" if value.include?(CoolId.separator)
89
+ value
90
+ end
20
91
  end
21
92
 
22
93
  module Model
23
94
  extend ActiveSupport::Concern
24
95
 
25
96
  class_methods do
26
- attr_accessor :cool_id_prefix, :cool_id_separator, :cool_id_alphabet, :cool_id_length
97
+ attr_reader :cool_id_config
98
+
99
+ def cool_id(options)
100
+ @cool_id_config = Config.new(**options)
101
+ CoolId.registry.register(options[:prefix], self)
102
+ end
27
103
 
28
104
  def generate_cool_id
29
- CoolId.generate_id(
30
- prefix: cool_id_prefix,
31
- separator: cool_id_separator || DEFAULT_SEPARATOR,
32
- length: cool_id_length || DEFAULT_LENGTH,
33
- alphabet: cool_id_alphabet || DEFAULT_ALPHABET
34
- )
105
+ CoolId.generate_id(@cool_id_config)
35
106
  end
36
107
  end
37
108
 
@@ -45,4 +116,12 @@ module CoolId
45
116
  end
46
117
  end
47
118
  end
119
+
120
+ def self.locate(id)
121
+ registry.locate(id)
122
+ end
123
+
124
+ def self.parse(id)
125
+ registry.parse(id)
126
+ end
48
127
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cool_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Schilling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-16 00:00:00.000000000 Z
11
+ date: 2024-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nanoid