diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index 14644bf297..546f06e947 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -458,6 +458,34 @@ defmodule String do @spec next_codepoint(t) :: {codepoint, t} | :no_codepoint defdelegate next_codepoint(string), to: String.Unicode + @doc %B""" + Checks whether `str` is a valid UTF-8 string. + + ## Examples + + iex> String.valid?("a") + true + iex> String.valid?("ø") + true + iex> String.valid?(<<0xffff :: 16>>) + false + iex> String.valid?("asd" <> <<0xffff :: 16>>) + false + + """ + @spec valid?(t) :: boolean + def valid?(<<_ :: utf8, t :: binary>>) do + valid?(t) + end + + def valid?(<<>>) do + true + end + + def valid?(_) do + false + end + @doc %B""" Checks whether `str` is a valid codepoint. @@ -470,7 +498,7 @@ defmodule String do true iex> String.valid_codepoint?("ø") true - iex> String.valid_codepoint?("\xffff") + iex> String.valid_codepoint?(<<0xffff :: 16>>) false iex> String.valid_codepoint?("asdf") false diff --git a/lib/elixir/test/elixir/string_test.exs b/lib/elixir/test/elixir/string_test.exs index 51d6e58491..b226cc1884 100644 --- a/lib/elixir/test/elixir/string_test.exs +++ b/lib/elixir/test/elixir/string_test.exs @@ -228,12 +228,21 @@ defmodule StringTest do assert String.slice("", 0, 1) == nil end + test :valid? do + assert String.valid?("afds") + assert String.valid?("øsdfh") + assert String.valid?("dskfjあska") + + refute String.valid?(<<0xffff :: 16>>) + refute String.valid?("asd" <> <<0xffff :: 16>>) + end + test :valid_codepoint? do assert String.valid_codepoint?("a") assert String.valid_codepoint?("ø") assert String.valid_codepoint?("あ") - refute String.valid_codepoint?("\xffff") + refute String.valid_codepoint?(<<0xffff :: 16>>) refute String.valid_codepoint?("ab") end