name.ex (2759B)
1 defmodule Credo.Code.Name do 2 @moduledoc """ 3 This module provides helper functions to process names of functions, module 4 attributes and modules. 5 """ 6 7 def last(name) when is_atom(name) do 8 name 9 |> to_string 10 |> String.split(".") 11 |> List.last() 12 end 13 14 def last(name) when is_binary(name) do 15 name 16 |> String.split(".") 17 |> List.last() 18 end 19 20 def last(mod_list) when is_list(mod_list) do 21 mod_list 22 |> List.last() 23 |> to_string 24 end 25 26 # Credo.Code.Name |> to_string 27 # => "Elixir.Credo.Code.Name" 28 def first(name) when is_atom(name) do 29 name 30 |> to_string 31 |> String.split(".") 32 |> Enum.at(1) 33 end 34 35 def first(name) when is_binary(name) do 36 name 37 |> String.split(".") 38 |> List.first() 39 end 40 41 def first(mod_list) when is_list(mod_list) do 42 mod_list 43 |> List.first() 44 |> to_string 45 end 46 47 def full(mod_list) when is_list(mod_list) do 48 Enum.map_join(mod_list, ".", &full/1) 49 end 50 51 def full(name) when is_atom(name) do 52 name 53 |> to_string 54 |> String.split(".") 55 |> name_from_splitted_parts 56 end 57 58 def full(name) when is_binary(name) do 59 name 60 end 61 62 def full(name) when is_integer(name) do 63 to_string(name) 64 end 65 66 def full({name, _, nil}) when is_atom(name) do 67 full(name) 68 end 69 70 def full({:__aliases__, _, mod_list}) do 71 full(mod_list) 72 end 73 74 def full({{:., _, [{:__aliases__, _, mod_list}, name]}, _, _}) do 75 full([full(mod_list), name]) 76 end 77 78 def full({:@, _, [{name, _, nil}]}) when is_atom(name) do 79 "@#{name}" 80 end 81 82 def full({name, _, arguments}) when is_atom(name) and is_list(arguments) do 83 arg_list = Enum.map_join(arguments, ", ", &full/1) 84 85 "#{full(name)}(#{arg_list})" 86 end 87 88 def parts_count(module_name) do 89 module_name 90 |> String.split(".") 91 |> length 92 end 93 94 def pascal_case?(name) do 95 String.match?(name, ~r/^[A-Z][a-zA-Z0-9]*$/) 96 end 97 98 def split_pascal_case(name) do 99 name 100 |> String.replace(~r/([A-Z])/, " \\1") 101 |> String.split() 102 end 103 104 def snake_case?(name) do 105 String.match?(name, ~r/^[[:lower:][:digit:]\_\?\!]+$/u) 106 end 107 108 def snake_case?(name, true) do 109 snake_case?(name) || snake_case_with_acronyms?(name) 110 end 111 112 def snake_case?(name, _) do 113 snake_case?(name) 114 end 115 116 defp snake_case_with_acronyms?(name) do 117 name 118 |> String.split("_") 119 |> Enum.all?(fn part -> 120 String.match?(part, ~r/^([[:lower:][:digit:]]+|[[:upper:][:digit:]]+)$/u) 121 end) 122 end 123 124 def no_case?(name) do 125 String.match?(name, ~r/^[^a-zA-Z0-9]+$/) 126 end 127 128 defp name_from_splitted_parts(parts) when length(parts) > 1 do 129 parts 130 |> Enum.slice(1, length(parts)) 131 |> Enum.join(".") 132 end 133 134 defp name_from_splitted_parts(parts) do 135 Enum.join(parts, ".") 136 end 137 end