Skip to content

Commit 98880e4

Browse files
authored
Implement ShortUUID.Behaviour (#13)
* implement behaviour * update readme
1 parent d0edc83 commit 98880e4

5 files changed

Lines changed: 134 additions & 1 deletion

File tree

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,57 @@ iex> SmileyUUID.encode("550e8400-e29b-41d4-a716-446655440000")
175175

176176
```
177177

178+
## Implementing Compatible Modules
179+
180+
Starting with version `v4.1.0`, ShortUUID provides a behavior that you can implement to create compatible modules.
181+
This is useful if you want to create your own ShortUUID-compatible module with custom functionality while maintaining a consistent interface.
182+
183+
```elixir
184+
defmodule MyCustomShortUUID do
185+
@behaviour ShortUUID.Behaviour
186+
187+
@spec encode(String.t()) :: {:ok, String.t()} | {:error, String.t()}
188+
def encode(uuid) do
189+
# Your custom implementation here
190+
{:ok, "encoded_" <> uuid}
191+
end
192+
193+
@spec encode!(String.t()) :: String.t() | no_return()
194+
def encode!(uuid) do
195+
case encode(uuid) do
196+
{:ok, encoded} -> encoded
197+
{:error, msg} -> raise ArgumentError, message: msg
198+
end
199+
end
200+
201+
@spec decode(String.t()) :: {:ok, String.t()} | {:error, String.t()}
202+
def decode(encoded) do
203+
# Your custom implementation here
204+
if String.starts_with?(encoded, "encoded_") do
205+
{:ok, String.replace_prefix(encoded, "encoded_", "")}
206+
else
207+
{:error, "Invalid format"}
208+
end
209+
end
210+
211+
@spec decode!(String.t()) :: String.t() | no_return()
212+
def decode!(encoded) do
213+
case decode(encoded) do
214+
{:ok, decoded} -> decoded
215+
{:error, msg} -> raise ArgumentError, message: msg
216+
end
217+
end
218+
end
219+
```
220+
221+
The `ShortUUID.Behaviour` requires implementing four callbacks:
222+
- `encode/1` - Encode a UUID into a shorter representation
223+
- `encode!/1` - Same as encode/1 but raises on error
224+
- `decode/1` - Decode a shortened UUID back to standard format
225+
- `decode!/1` - Same as decode/1 but raises on error
226+
227+
Using this behavior ensures that your custom implementation will be compatible with code expecting a ShortUUID-compatible module.
228+
178229
## Documentation
179230

180231
Look up the full documentation at [https://hexdocs.pm/shortuuid](https://hexdocs.pm/shortuuid).

lib/shortuuid.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ defmodule ShortUUID do
1818
{:ok, "550e8400-e29b-41d4-a716-446655440000"}
1919
2020
For custom alphabets and more options, see `ShortUUID.Builder`.
21+
To implement your own compatible ShortUUID module, use `ShortUUID.Behaviour`.
2122
"""
2223
use ShortUUID.Builder, alphabet: :base57_shortuuid
2324
end

lib/shortuuid/behaviour.ex

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
defmodule ShortUUID.Behaviour do
2+
@moduledoc """
3+
Defines the behavior for ShortUUID-compatible modules.
4+
5+
This behavior ensures consistent interface across different ShortUUID implementations.
6+
Any module implementing this behavior should provide encode/decode functionality
7+
for converting UUIDs to shorter string representations and back.
8+
9+
## Required Callbacks
10+
11+
- `encode/1` - Encodes a standard UUID into a shorter string
12+
- `encode!/1` - Encodes a UUID, raising an exception on invalid input
13+
- `decode/1` - Decodes a shortened UUID string back into standard UUID format
14+
- `decode!/1` - Decodes a shortened UUID, raising an exception on invalid input
15+
"""
16+
17+
@doc """
18+
Encodes a UUID string into a shorter string representation.
19+
20+
## Parameters
21+
22+
- `uuid` - A standard UUID string (with or without hyphens)
23+
24+
## Returns
25+
26+
- `{:ok, encoded}` - Successfully encoded string
27+
- `{:error, message}` - Error with descriptive message
28+
"""
29+
@callback encode(uuid :: String.t()) :: {:ok, String.t()} | {:error, String.t()}
30+
31+
@doc """
32+
Encodes a UUID string into a shorter string representation.
33+
Raises an ArgumentError if the input is invalid.
34+
35+
## Parameters
36+
37+
- `uuid` - A standard UUID string (with or without hyphens)
38+
39+
## Returns
40+
41+
- `encoded` - Successfully encoded string
42+
43+
## Raises
44+
45+
- `ArgumentError` - If the input is invalid
46+
"""
47+
@callback encode!(uuid :: String.t()) :: String.t() | no_return()
48+
49+
@doc """
50+
Decodes a shortened UUID string back into standard UUID format.
51+
52+
## Parameters
53+
54+
- `string` - A shortened UUID string
55+
56+
## Returns
57+
58+
- `{:ok, uuid}` - Successfully decoded UUID
59+
- `{:error, message}` - Error with descriptive message
60+
"""
61+
@callback decode(string :: String.t()) :: {:ok, String.t()} | {:error, String.t()}
62+
63+
@doc """
64+
Decodes a shortened UUID string back into standard UUID format.
65+
Raises an ArgumentError if the input is invalid.
66+
67+
## Parameters
68+
69+
- `string` - A shortened UUID string
70+
71+
## Returns
72+
73+
- `uuid` - Successfully decoded UUID
74+
75+
## Raises
76+
77+
- `ArgumentError` - If the input is invalid
78+
"""
79+
@callback decode!(string :: String.t()) :: String.t() | no_return()
80+
end

lib/shortuuid/builder.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ defmodule ShortUUID.Builder do
7070
quote do
7171
import Bitwise
7272
alias ShortUUID.Core
73+
@behaviour ShortUUID.Behaviour
7374

7475
@alphabet unquote(validated_alphabet)
7576
@padding_char unquote(padding_char)

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ShortUUID.Mixfile do
22
use Mix.Project
33

44
@name "ShortUUID"
5-
@version "4.0.0"
5+
@version "4.1.0"
66
@url "https://github.com/gpedic/ex_shortuuid"
77

88
def project do

0 commit comments

Comments
 (0)