Skip to content

Commit 48facf6

Browse files
committed
Initial commit
0 parents  commit 48facf6

File tree

11 files changed

+276
-0
lines changed

11 files changed

+276
-0
lines changed

.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Ignore .fetch files in case you like to edit your project deps locally.
14+
/.fetch
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
unicode_guards-*.tar
24+

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog for Unicode Guards v0.1.0
2+
3+
This is the changelog for Unicode Guards v0.1.0 released on November 23rd, 2019. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-unicode/unicode_guards/tags)
4+
5+
Initial release.

LICENSE.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# License
2+
3+
Copyright 2019 Kip Cole
4+
5+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
6+
compliance with the License. You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software distributed under the License
11+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
implied. See the License for the specific language governing permissions and limitations under the
13+
License.

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Unicode Guards
2+
3+
Provides a set of function guards that can be used to match Unicode codepoints. Based upon [ex_unicode](https://hex.pm/packages/ex_unicode) and [unicode_set](https://hex.pm/packages/unicode_set).
4+
5+
## Usage
6+
7+
Each guard operates on a UTF8 codepoint since the permitted operators in a guard clause are restricted to simple comparisons that do not include strings.
8+
9+
The data that underpins these guards is generated from the Unicode character database and therefore
10+
includes a broad range of scripts well beyond the basic ASCII definitions.
11+
12+
Some examples follow defining functions using the pre-defined guards. Note that since guards operate on codepoints (not strings) we use binary pattern matching to extract the first codepoint for these example.
13+
14+
```elixir
15+
defmodule Guards do
16+
import Unicode.Guards
17+
18+
def upper(<< x :: utf8, _rest :: binary >>) when is_upper(x), do: :upper
19+
def lower(<< x :: utf8, _rest :: binary >>) when is_lower(x), do: :lower
20+
def digit(<< x :: utf8, _rest :: binary >>) when is_digit(x), do: :digit
21+
def whitespace(<< x :: utf8, _rest :: binary >>) when is_whitespace(x), do: :whitespace
22+
def currency(<< x :: utf8, _rest :: binary >>) when is_currency_symbol(x), do: :currency
23+
end
24+
```
25+
## Installation
26+
27+
The package can be installed by adding `unicode_guards` to your list of dependencies in `mix.exs`:
28+
29+
```elixir
30+
def deps do
31+
[
32+
{:unicode_guards, "~> 0.1.0"}
33+
]
34+
end
35+
```
36+
37+
The docs can be found at [https://hexdocs.pm/unicode_guards](https://hexdocs.pm/unicode_guards).
38+

lib/unicode_guards.ex

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
defmodule Unicode.Guards do
2+
@moduledoc """
3+
Defines a set of guards that can be used with
4+
Elixir functions.
5+
6+
Each guard operates on a UTF8 codepoint since
7+
the permitted operators in a guard clause
8+
are restricted to simple comparisons that do
9+
not include string comparators.
10+
11+
The data that underpins these guards is generated
12+
from the Unicode character database and therefore
13+
includes a broad range of scripts well beyond
14+
the basic ASCII definitions.
15+
16+
"""
17+
18+
require Unicode.Set
19+
import Unicode.Set, only: [match?: 2]
20+
import Kernel, except: [match?: 2]
21+
22+
@doc """
23+
Guards whether a UTF8 codepoint is an upper case
24+
character.
25+
26+
The match is for any UTF8 character that is defined
27+
in Unicode to be an upper case character in any
28+
script.
29+
30+
"""
31+
defguard is_upper(codepoint) when is_integer(codepoint) and match?(codepoint, "[[:Lu:]]")
32+
33+
@doc """
34+
Guards whether a UTF8 codepoint is a lower case
35+
character.
36+
37+
The match is for any UTF8 character that is defined
38+
in Unicode to be an lower case character in any
39+
script.
40+
41+
"""
42+
defguard is_lower(codepoint) when is_integer(codepoint) and match?(codepoint, "[[:Ll:]]")
43+
44+
@doc """
45+
Guards whether a UTF8 codepoint is a digit
46+
character.
47+
48+
This guard will match any digit character from any
49+
Unicode script, not only the ASCII decimal digits.
50+
51+
"""
52+
defguard is_digit(codepoint) when is_integer(codepoint) and match?(codepoint, "[[:Nd:]]")
53+
54+
@doc """
55+
Guards whether a UTF8 codepoint is a currency symbol
56+
character.
57+
58+
"""
59+
defguard is_currency_symbol(codepoint)
60+
when is_integer(codepoint) and match?(codepoint, "[[:Sc:]]")
61+
62+
63+
@doc """
64+
Guards whether a UTF8 codepoint is a whitespace symbol
65+
character.
66+
67+
"""
68+
defguard is_whitespace(codepoint) when is_integer(codepoint) and match?(codepoint, "[[:Zs:]]")
69+
70+
end

logo.png

38 KB
Loading

mix.exs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
defmodule Unicode.Guards.MixProject do
2+
use Mix.Project
3+
4+
@version "0.1.0"
5+
6+
def project do
7+
[
8+
app: :unicode_guards,
9+
version: @version,
10+
elixir: "~> 1.8",
11+
start_permanent: Mix.env() == :prod,
12+
build_embedded: Mix.env() == :prod,
13+
deps: deps(),
14+
docs: docs(),
15+
name: "Unicode function guards for Elixir",
16+
source_url: "https://github.com/elixir-unicode/unicode_guards",
17+
description: description(),
18+
package: package(),
19+
elixirc_paths: elixirc_paths(Mix.env())
20+
]
21+
end
22+
23+
defp description do
24+
"""
25+
Implementation of Unicode Set-based guards for Elixir. Supports matching
26+
unicode sets to codepoints that can be used in function guards.
27+
"""
28+
end
29+
30+
defp package do
31+
[
32+
maintainers: ["Kip Cole"],
33+
licenses: ["Apache 2.0"],
34+
logo: "logo.png",
35+
links: links(),
36+
files: [
37+
"lib",
38+
"logo.png",
39+
"mix.exs",
40+
"README*",
41+
"CHANGELOG*",
42+
"LICENSE*"
43+
]
44+
]
45+
end
46+
47+
def application do
48+
[
49+
extra_applications: [:logger]
50+
]
51+
end
52+
53+
defp deps do
54+
[
55+
{:ex_unicode, "~> 1.1"},
56+
{:unicode_set, "~> 0.1"},
57+
{:nimble_parsec, "~> 0.5", runtime: false},
58+
{:benchee, "~> 1.0", only: :dev},
59+
{:ex_doc, "~> 0.19", only: [:dev, :test, :release], runtime: false}
60+
]
61+
end
62+
63+
def links do
64+
%{
65+
"GitHub" => "https://github.com/elixir-unicode/unicode_guards",
66+
"Readme" => "https://github.com/elixir-unicode/unicode_guards/blob/v#{@version}/README.md",
67+
"Changelog" => "https://github.com/elixir-unicode/unicode_guards/blob/v#{@version}/CHANGELOG.md"
68+
}
69+
end
70+
71+
def docs do
72+
[
73+
source_ref: "v#{@version}",
74+
main: "readme",
75+
logo: "logo.png",
76+
extras: [
77+
"README.md",
78+
"LICENSE.md",
79+
"CHANGELOG.md"
80+
],
81+
skip_undefined_reference_warnings_on: ["changelog"]
82+
]
83+
end
84+
85+
defp elixirc_paths(:test), do: ["lib", "test"]
86+
defp elixirc_paths(:dev), do: ["lib", "bench"]
87+
defp elixirc_paths(_), do: ["lib"]
88+
end

mix.lock

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
%{
2+
"benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"},
3+
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm"},
4+
"earmark": {:hex, :earmark, "1.4.2", "3aa0bd23bc4c61cf2f1e5d752d1bb470560a6f8539974f767a38923bb20e1d7f", [:mix], [], "hexpm"},
5+
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
6+
"ex_unicode": {:hex, :ex_unicode, "1.1.0", "95e8ed3fb3a3688a365c85a60e2aa79a20426ed3d2ca1516389324f71efca842", [:mix], [], "hexpm"},
7+
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
8+
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
9+
"nimble_parsec": {:hex, :nimble_parsec, "0.5.2", "1d71150d5293d703a9c38d4329da57d3935faed2031d64bc19e77b654ef2d177", [:mix], [], "hexpm"},
10+
"unicode_set": {:hex, :unicode_set, "0.1.0", "d32d23953702baeb89da0486cad22eeb8817bb8050571250248da443ba73983a", [:mix], [{:ex_unicode, "~> 1.1", [hex: :ex_unicode, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
11+
}

test/test_helper.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ExUnit.start()

0 commit comments

Comments
 (0)