-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
64 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
name = "UUID4" | ||
uuid = "379725f3-1ad5-416d-b88a-50ced391fe04" | ||
authors = ["Heptazhou <zhou at 0h7z dot com>"] | ||
version = "1.8.0" | ||
version = "1.10.0" | ||
|
||
[deps] | ||
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" | ||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" | ||
|
||
[extras] | ||
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" | ||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" | ||
|
||
[targets] | ||
test = ["Test"] | ||
test = ["OrderedCollections", "Test"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Copyright (C) 2022-2023 Heptazhou <[email protected]> | ||
# Copyright (C) 2022-2024 Heptazhou <[email protected]> | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
|
@@ -16,29 +16,31 @@ | |
""" | ||
UUID4 | ||
The `UUID4` module provides universally unique identifier (UUID), version 4, | ||
This module provides universally unique identifier (UUID) version 4, | ||
along with related functions. | ||
""" | ||
module UUID4 | ||
|
||
export uuid, uuid4 | ||
|
||
export uuid_formats | ||
export uuid_parse | ||
export uuid_string | ||
export uuid_tryparse | ||
export uuid_version | ||
|
||
export AbstractRNG, MersenneTwister, RandomDevice | ||
export LittleDict, OrderedDict | ||
export UUID | ||
|
||
const Maybe{T} = Union{Nothing, T} | ||
const UUID = Base.UUID | ||
using OrderedCollections: LittleDict, OrderedDict | ||
using Random: AbstractRNG, MersenneTwister, RandomDevice | ||
|
||
""" | ||
uuid(rng::AbstractRNG = RandomDevice()) -> UUID | ||
uuid(rng::AbstractRNG = Random.RandomDevice()) -> UUID | ||
Generate a version 4 (random or pseudo-random) universally unique identifier | ||
(UUID), as specified by [RFC 4122](https://www.ietf.org/rfc/rfc4122). | ||
Generate a version 4 (random or pseudo-random) universally unique identifier (UUID), | ||
as specified by [RFC 4122](https://tools.ietf.org/html/rfc4122). | ||
# Examples | ||
```jldoctest | ||
|
@@ -76,39 +78,22 @@ function uuid_formats()::Vector{Int} | |
end | ||
|
||
""" | ||
uuid_parse(str::String; fmt::Int = length(str)) -> Tuple{Int, UUID} | ||
uuid_parse(str::AbstractString; fmt::Int = length(str)) -> Tuple{Int, UUID} | ||
""" | ||
function uuid_parse end | ||
function uuid_parse(str::UUID; fmt::Any = 0x0)::Tuple{Int, UUID} | ||
uuid_parse(string(str); fmt = Int(fmt)) | ||
function uuid_parse(id::UUID)::Tuple{Int, UUID} | ||
(length("$id"), id) # (36, id) | ||
end | ||
function uuid_parse(str::Any; fmt::Number = 0)::Tuple{Int, UUID} | ||
uuid_parse(String(str); fmt = Int(fmt)) | ||
end | ||
function uuid_parse(str::String; fmt::Int = 0)::Tuple{Int, UUID} | ||
function uuid_parse(str::AbstractString; fmt::Int = 0)::Tuple{Int, UUID} | ||
len = length(str) | ||
ret = if 0 > fmt | ||
argumenterror("Invalid format `$fmt` (should be positive)") | ||
elseif len ≠ fmt > 0 | ||
argumenterror("Invalid id `$str` with length = $len (should be $fmt)") | ||
elseif len ≡ 24 | ||
uuid_parse(replace((str), "-" => ""), fmt = 22)[end] | ||
elseif len ≡ 29 | ||
uuid_parse(replace((str), "-" => ""), fmt = 25)[end] | ||
elseif len ≡ 39 | ||
uuid_parse(replace((str), "-" => ""), fmt = 32)[end] | ||
elseif len ≡ 22 | ||
UUID(parse(UInt128, str, base = 62)) | ||
elseif len ≡ 25 | ||
UUID(parse(UInt128, str, base = 36)) | ||
elseif len ≡ 32 | ||
UUID(parse(UInt128, str, base = 16)) | ||
elseif len ≡ 36 | ||
UUID(str) | ||
else | ||
(id = uuid_tryparse(str)) |> isnothing && | ||
argumenterror("Invalid id `$str` with length = $len") | ||
if 0 < fmt ≠ len | ||
argumenterror("Invalid id `$str` with length = $len (should be $fmt)") | ||
elseif fmt < 0 | ||
argumenterror("Invalid format `$fmt` (should be positive)") | ||
end | ||
len, ret | ||
len, id |> UUID | ||
end | ||
|
||
""" | ||
|
@@ -159,33 +144,38 @@ function uuid_string(fmt::Int, id::UUID = uuid())::String | |
uuid_string(id, fmt) | ||
end | ||
function uuid_string(id::UUID, fmt::Int)::String | ||
if 0 ≥ fmt | ||
argumenterror("Invalid format `$fmt` (should be positive)") | ||
elseif fmt ≡ 36 | ||
string(id) | ||
elseif fmt ≡ 22 | ||
string(id.value, base = 62, pad = fmt) | ||
elseif fmt ≡ 25 | ||
string(id.value, base = 36, pad = fmt) | ||
elseif fmt ≡ 32 | ||
string(id.value, base = 16, pad = fmt) | ||
elseif fmt ≡ 24 | ||
replace(uuid_string(id, 22), r"(.{7})" => s"\1-", count = fmt - 22) | ||
elseif fmt ≡ 29 | ||
replace(uuid_string(id, 25), r"(.{5})" => s"\1-", count = fmt - 25) | ||
elseif fmt ≡ 39 | ||
replace(uuid_string(id, 32), r"(.{4})" => s"\1-", count = fmt - 32) | ||
else | ||
argumenterror("Invalid format `$fmt` (undefined)") | ||
end | ||
fmt ≤ 0 ? | ||
argumenterror("Invalid format `$fmt` (should be positive)") : | ||
fmt ≡ 36 ? string(id) : | ||
fmt ≡ 22 ? string(id.value, base = 62, pad = fmt) : | ||
fmt ≡ 25 ? string(id.value, base = 36, pad = fmt) : | ||
fmt ≡ 32 ? string(id.value, base = 16, pad = fmt) : | ||
fmt ≡ 24 ? replace(uuid_string(id, 22), r"(.{7})" => s"\1-", count = fmt - 22) : | ||
fmt ≡ 29 ? replace(uuid_string(id, 25), r"(.{5})" => s"\1-", count = fmt - 25) : | ||
fmt ≡ 39 ? replace(uuid_string(id, 32), r"(.{4})" => s"\1-", count = fmt - 32) : | ||
argumenterror("Invalid format `$fmt` (not defined)") | ||
end | ||
|
||
""" | ||
uuid_tryparse(s::AbstractString) -> Maybe{Union{UInt128, UUID}} | ||
""" | ||
function uuid_tryparse(str::AbstractString)::Maybe{Union{UInt128, UUID}} | ||
len = ncodeunits(str) | ||
len ≡ 24 ? uuid_tryparse(replace(str, "-" => "")) : | ||
len ≡ 29 ? uuid_tryparse(replace(str, "-" => "")) : | ||
len ≡ 39 ? uuid_tryparse(replace(str, "-" => "")) : | ||
len ≡ 22 ? Base.tryparse(UInt128, str, base = 62) : | ||
len ≡ 25 ? Base.tryparse(UInt128, str, base = 36) : | ||
len ≡ 32 ? Base.tryparse(UInt128, str, base = 16) : | ||
len ≡ 36 ? Base.tryparse(UUID, str) : nothing | ||
end | ||
|
||
""" | ||
uuid_version(id::String) -> Int | ||
uuid_version(id::UUID) -> Int | ||
uuid_version(id::AbstractString) -> Int | ||
uuid_version(id::UUID) -> Int | ||
Inspect the given UUID or UUID string and return its version (see [RFC | ||
4122](https://www.ietf.org/rfc/rfc4122)). | ||
Inspect the given UUID or UUID string and return its version | ||
(see [RFC 4122](https://tools.ietf.org/html/rfc4122)). | ||
# Examples | ||
```jldoctest | ||
|
@@ -194,9 +184,8 @@ julia> uuid_version(uuid()) | |
``` | ||
""" | ||
function uuid_version end | ||
uuid_version(id::Any)::Int = uuid_version(String(id)) | ||
uuid_version(id::String)::Int = uuid_version(uuid_parse(id)[end]) | ||
uuid_version(id::UUID)::Int = Int(id.value >> 76 & 0xf) | ||
uuid_version(id::Any)::Int = uuid_version(uuid_parse(id)[end]) | ||
uuid_version(id::UUID)::Int = id.value >> 76 & 0xf |> Int | ||
|
||
@noinline argumenterror(msg::AbstractString) = throw(ArgumentError(msg)) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Copyright (C) 2022-2023 Heptazhou <[email protected]> | ||
# Copyright (C) 2022-2024 Heptazhou <[email protected]> | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
|
@@ -13,6 +13,7 @@ | |
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
||
using OrderedCollections: LittleDict, OrderedDict | ||
using Random: Random | ||
using Test, UUID4 | ||
|
||
|
@@ -40,7 +41,7 @@ str = "22b4a8a1-e548-4eeb-9270-60426d66a48e" | |
@test_throws ArgumentError UUID("22b4a8a1-e548-4eeba9270-60426d66a48e") | ||
@test_throws ArgumentError UUID("22b4a8a1-e548-4eeb-9270a60426d66a48e") | ||
@test UUID(uppercase(str)) == UUID(str) | ||
for r in (rand(UInt128, 10^3)) | ||
for r ∈ rand(UInt128, 10^3) | ||
@test UUID(r) == UUID(string(UUID(r))) | ||
end | ||
|
||
|
@@ -58,9 +59,10 @@ d_o, d_u = OrderedDict(vec), Dict(vec) | |
u = UUID(d_u[36]) | ||
s = GenericString(string(u)) | ||
|
||
@test uuid_tryparse("") |> isnothing | ||
@test uuid_parse(s) == uuid_parse(u) == (36, u) | ||
@test uuid_formats() == d_o.keys == fmt | ||
for n in fmt | ||
for n ∈ fmt | ||
@test (n, u) == uuid_parse(d_u[n]) == uuid_parse(d_u[n] |> GenericString) | ||
@test d_u[n] == uuid_string(n, u) == uuid_string(u, n |> UInt32) == d_o[n] | ||
@test d_o[n] == uuid_string(n, u |> string) == uuid_string(u |> string, n) | ||
|
@@ -71,9 +73,10 @@ end | |
@test_throws ArgumentError uuid_parse(d_u[32], fmt = 42) | ||
@test_throws ArgumentError uuid_parse(d_u[32]^2) | ||
|
||
@test uuid_string(u, LittleDict) == uuid_string(LittleDict, u) | ||
@test uuid_string(u, OrderedDict) == uuid_string(OrderedDict, u) | ||
@test uuid_string(u) == uuid_string(Dict, u) == d_u == Dict(d_o) | ||
@test uuid_string(u) == uuid_string(Dict, s) == uuid_string(s, Dict) | ||
@test uuid_string(u) == uuid_string(s, Dict) == uuid_string(Dict, s) | ||
@test_throws ArgumentError uuid_string(u, -1) | ||
@test_throws ArgumentError uuid_string(u, 42) | ||
|