{"id":13509713,"url":"https://github.com/DOBRO/uef-lib","last_synced_at":"2025-03-30T13:32:46.248Z","repository":{"id":62430646,"uuid":"182101944","full_name":"DOBRO/uef-lib","owner":"DOBRO","description":"Useful Erlang Functions Library","archived":false,"fork":false,"pushed_at":"2024-09-13T16:08:46.000Z","size":204,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-21T08:11:41.381Z","etag":null,"topics":["binaries","bytes-formatting","datetime","erlang","file-reading","functional-programming","html-entities","lists","nested-maps","number-formating","otp-library"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DOBRO.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-18T14:22:59.000Z","updated_at":"2024-09-13T16:08:49.000Z","dependencies_parsed_at":"2023-12-27T15:33:59.183Z","dependency_job_id":"5935a0f0-a14b-40e5-9632-a94338550f51","html_url":"https://github.com/DOBRO/uef-lib","commit_stats":{"total_commits":268,"total_committers":2,"mean_commits":134.0,"dds":"0.014925373134328401","last_synced_commit":"765d28837584bcfced1aae5d5f831972ec0254bb"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DOBRO%2Fuef-lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DOBRO%2Fuef-lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DOBRO%2Fuef-lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DOBRO%2Fuef-lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DOBRO","download_url":"https://codeload.github.com/DOBRO/uef-lib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246324311,"owners_count":20759108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binaries","bytes-formatting","datetime","erlang","file-reading","functional-programming","html-entities","lists","nested-maps","number-formating","otp-library"],"created_at":"2024-08-01T02:01:11.903Z","updated_at":"2025-03-30T13:32:45.935Z","avatar_url":"https://github.com/DOBRO.png","language":"Erlang","funding_links":[],"categories":["Utilities","General Libraries"],"sub_categories":[],"readme":"= uef-lib\n:toc: macro\n:toclevels: 4\n\nimage:https://img.shields.io/hexpm/v/uef.svg?color=yellow[\"uef-lib on Hex.pm\", link=\"https://hex.pm/packages/uef\"]\nimage:https://github.com/DOBRO/uef-lib/actions/workflows/main.yml/badge.svg?branch=master[\"Build Status\", link=\"https://github.com/DOBRO/uef-lib/actions/workflows/main.yml?query=branch%3Amaster\"]\nimage:https://codecov.io/gh/DOBRO/uef-lib/branch/master/graph/badge.svg[\"Code coverage\", link=\"https://app.codecov.io/gh/DOBRO/uef-lib\"]\nimage:https://img.shields.io/badge/license-Apache%202.0-blue.svg[\"License\", link=\"LICENSE\"]\n\n\n*uef-lib* is a **U**seful **E**rlang **F**unctions **Lib**rary that provides modules for manipulating lists, binaries, maps, numbers, date and time.\nIt can be used in OTP applications and contains some functions optimized for performance in specific cases (e.g. for file I/O operations or binary transformations).\n\nErlang/OTP 19 or higher is required.\n\nSee how to link:#build[build] and link:#test-and-dialyze[test].\n\n'''\n\ntoc::[]\n\n'''\n\n== Installation\n\n=== For Erlang projects\n\nAdd `uef-lib` as a dependency to your `rebar.config` file:\n\n[source,erlang]\n----\n{deps, [\n  {uef, \"2.6.0\"}\n]}.\n----\n\n=== For Elixir projects\n\nAdd `uef-lib` as a dependency to your `mix.exs` file:\n\n[source,elixir]\n----\ndefp deps do\n  [\n    {:uef, \"~\u003e 2.6.0\"}\n  ]\nend\n----\n\n== Modules\n\n* *link:#module-uef_bin[uef_bin]* - for binaries.\n* *link:#module-uef_crypt[uef_crypt]* - some crypto functions.\n* *link:#module-uef_encode[uef_encode]* - working with encodings.\n* *link:#module-uef_file[uef_file]* - working with files.\n* *link:#module-uef_format[uef_format]* - formatting numbers.\n* *link:#module-uef_lists[uef_lists]* - lists transformations.\n* *link:#module-uef_maps[uef_maps]* - functions for maps processing.\n* *link:#module-uef_num[uef_num]* - helpful functions for numbers.\n* *link:#module-uef_time[uef_time]* - datetime functions.\n\n== Documentation\n\n=== Module `uef_bin`\n\n'''\n\n==== uef_bin:chomp/1\n\n[source,erlang]\n----\nuef_bin:chomp(Binary1 :: binary()) -\u003e Binary2 :: binary().\n----\n\nRemoves all trailing `\\n` and `\\r` characters from `Binary1`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:chomp(\u003c\u003c\"string\\r\\n\"\u003e\u003e).\n\u003c\u003c\"string\"\u003e\u003e\n\n\u003e uef_bin:chomp(\u003c\u003c\"string\\r\\n\\r\\n\"\u003e\u003e).\n\u003c\u003c\"string\"\u003e\u003e\n\n\u003e uef_bin:chomp(\u003c\u003c\"string\\n\\n\\n\\n\"\u003e\u003e).\n\u003c\u003c\"string\"\u003e\u003e\n\n\u003e uef_bin:chomp(\u003c\u003c\"string\\r\\r\\r\\r\"\u003e\u003e).\n\u003c\u003c\"string\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:binary_join/2\n\n[source,erlang]\n----\nuef_bin:binary_join(ListOfBinaries, Separator) -\u003e Binary.\n----\n\nJoins a list of binaries with separator into a single binary. Returns binary.\n\n*Example:*\n\n[source,erlang]\n----\n\u003e uef_bin:binary_join([\u003c\u003c\"www\"\u003e\u003e, \u003c\u003c\"example\"\u003e\u003e, \u003c\u003c\"com\"\u003e\u003e], \u003c\u003c\".\"\u003e\u003e).\n\u003c\u003c\"www.example.com\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:repeat/2\n\n[source,erlang]\n----\nuef_bin:repeat(Binary1, N) -\u003e Binary2.\n----\n\nReturns binary `Binary2` consisting of `Binary1` repeated `N` times.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:repeat(\u003c\u003c\"a\"\u003e\u003e, 10).\n\u003c\u003c\"aaaaaaaaaa\"\u003e\u003e\n\n\u003e uef_bin:repeat(\u003c\u003c\"0\"\u003e\u003e, 3).\n\u003c\u003c\"000\"\u003e\u003e\n\n\u003e uef_bin:repeat(\u003c\u003c0\u003e\u003e, 3).\n\u003c\u003c0,0,0\u003e\u003e\n\n\u003e uef_bin:repeat(\u003c\u003c1,1\u003e\u003e, 3).\n\u003c\u003c1,1,1,1,1,1\u003e\u003e\n\n\u003e uef_bin:repeat(\u003c\u003c\"abc\"\u003e\u003e, 3).\n\u003c\u003c\"abcabcabc\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:reverse/1\n\n[source,erlang]\n----\nuef_bin:reverse(Binary1) -\u003e Binary2.\n----\n\nReturns a binary in reverse *byte* order.\n\n**Note:** this function is **not** intended to work with UTF-8 binary strings. To get a binary in reverse *character* order, use link:#uef_binreverse_utf81[uef_bin:reverse_utf8/1] instead.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:reverse(\u003c\u003c\"ABCDEFGH\"\u003e\u003e).\n\u003c\u003c\"HGFEDCBA\"\u003e\u003e\n\n\u003e uef_bin:reverse(\u003c\u003c1,2,3,4,5\u003e\u003e).\n\u003c\u003c5,4,3,2,1\u003e\u003e\n\n\u003e uef_bin:reverse(\u003c\u003c\u003e\u003e).\n\u003c\u003c\u003e\u003e\n----\n\n'''\n\n==== uef_bin:reverse_utf8/1\n\n[source,erlang]\n----\nuef_bin:reverse_utf8(UTF8_Binary1) -\u003e UTF8_Binary2.\n----\n\nReturns a binary in reverse character order. Intended to work with UTF-8 binary strings.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:reverse_utf8(\u003c\u003c\"ABCDEFGH\"\u003e\u003e).\n\u003c\u003c\"HGFEDCBA\"\u003e\u003e\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c1,2,3,4,5\u003e\u003e).\n\u003c\u003c5,4,3,2,1\u003e\u003e\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c\"die Straße\"/utf8\u003e\u003e).\n\u003c\u003c\"eßartS eid\"/utf8\u003e\u003e\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c\"АБВГДЕЁЖ\"/utf8\u003e\u003e) =:= \u003c\u003c\"ЖЁЕДГВБА\"/utf8\u003e\u003e.\ntrue\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c1, 2, 3, \"АБВГДЕЁЖ\"/utf8, 4, 5, 6, 7\u003e\u003e) =:= \u003c\u003c7, 6, 5, 4, \"ЖЁЕДГВБА\"/utf8, 3, 2, 1\u003e\u003e.\ntrue\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c\"這條街\"/utf8\u003e\u003e) =:= \u003c\u003c\"街條這\"/utf8\u003e\u003e.\ntrue\n\n\u003e uef_bin:reverse_utf8(\u003c\u003c\"こんにちは\"/utf8\u003e\u003e) =:= \u003c\u003c\"はちにんこ\"/utf8\u003e\u003e.\ntrue\n----\n\n'''\n\n==== uef_bin:split/2\n\n[source,erlang]\n----\nuef_bin:split(Binary, Splitter) -\u003e ListOfBinaries.\n----\n\nSplits binary `Binary` with splitter `Splitter` into a list of binaries. Works as http://erlang.org/doc/man/binary.html#split-2[binary:split/2] but is more performant in simple cases.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:split(\u003c\u003c\".www.example.com.\"\u003e\u003e, \u003c\u003c\".\"\u003e\u003e).\n[\u003c\u003c\u003e\u003e,\u003c\u003c\"www\"\u003e\u003e,\u003c\u003c\"example\"\u003e\u003e,\u003c\u003c\"com\"\u003e\u003e,\u003c\u003c\u003e\u003e]\n\n\u003e uef_bin:split(\u003c\u003c\"www.example.com\"\u003e\u003e, \u003c\u003c\".\"\u003e\u003e).\n[\u003c\u003c\"www\"\u003e\u003e,\u003c\u003c\"example\"\u003e\u003e,\u003c\u003c\"com\"\u003e\u003e]\n\n\u003e uef_bin:split(\u003c\u003c\"www.example.com\"\u003e\u003e, \u003c\u003c\"A\"\u003e\u003e).\n[\u003c\u003c\"www.example.com\"\u003e\u003e]\n----\n\n'''\n\n==== uef_bin:split/3\n\n[source,erlang]\n----\nuef_bin:split(Binary, Splitter, 'trim_all') -\u003e ListOfBinaries.\n----\n\nSplits binary `Binary` with splitter `Splitter` into a list of binaries. Works as `uef_bin:split/2` but removes all epmty (`\u003c\u003c\u003e\u003e`) chunks. It can be used in simple cases instead of http://erlang.org/doc/man/binary.html#split-3[binary:split/3] for the reason that it's more performant.\n\n*Example:*\n\n[source,erlang]\n----\n\u003e uef_bin:split(\u003c\u003c\"..www.example.com.\"\u003e\u003e, \u003c\u003c\".\"\u003e\u003e, trim_all).\n[\u003c\u003c\"www\"\u003e\u003e,\u003c\u003c\"example\"\u003e\u003e,\u003c\u003c\"com\"\u003e\u003e]\n----\n\n'''\n\n==== uef_bin:replace/3\n\n[source,erlang]\n----\nuef_bin:replace(Binary1, Chars, OtherChars) -\u003e Binary2.\n----\n\nReplaces chars `Chars` with other chars `OtherChars` in binary `Binary1` and returns another binary `Binary2`. Works as http://erlang.org/doc/man/binary.html#replace-3[binary:replace/3] but more permormant and can be used in simple cases.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:replace(\u003c\u003c\"abcdefgbc\"\u003e\u003e, \u003c\u003c\"bc\"\u003e\u003e, \u003c\u003c\"ZZ\"\u003e\u003e).\n\u003c\u003c\"aZZdefgZZ\"\u003e\u003e\n\n\u003e uef_bin:replace(\u003c\u003c\"abcdefgbc\"\u003e\u003e, \u003c\u003c\"d\"\u003e\u003e, \u003c\u003c\"ZZ\"\u003e\u003e).\n\u003c\u003c\"abcZZefgbc\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:replace_chars/3\n\n[source,erlang]\n----\nuef_bin:replace_chars(Binary1, ListOfCharsToReplace, OtherChars) -\u003e Binary2.\n----\n\nReplaces chars inluded in list `ListOfCharsToReplace` with other chars `OtherChars` in binary `Binary1` and returns another binary `Binary2`.\n\n*Examples:*\n\n[source,erlang]\n----\nuef_bin:replace_chars(\u003c\u003c\"..www.example.com.\"\u003e\u003e, [\u003c\u003c\".\"\u003e\u003e], \u003c\u003c\u003e\u003e).\n\u003c\u003c\"wwwexamplecom\"\u003e\u003e\n\nuef_bin:replace_chars(\u003c\u003c\"..www.example.com.\"\u003e\u003e, [\u003c\u003c\".\"\u003e\u003e, \u003c\u003c\"w\"\u003e\u003e], \u003c\u003c\u003e\u003e).\n\u003c\u003c\"examplecom\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:random_latin_binary/2\n\n[source,erlang]\n----\nuef_bin:random_latin_binary(Length, CaseFlag) -\u003e RandomLatinBinary.\n----\n\nReturns a random binary of size `Length` consisting of latins `[a-zA-Z]` and digits `[0-9]`. The second argument `CaseFlag` corresponds to a letter case, an atom `'lower'`, `'upper'` or `'any'`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:random_latin_binary(10, lower).\n\u003c\u003c\"n0ui89sfsb\"\u003e\u003e\n\n\u003e uef_bin:random_latin_binary(10, upper).\n\u003c\u003c\"S11Y3DHEJI\"\u003e\u003e\n\n\u003e uef_bin:random_latin_binary(10, any).\n\u003c\u003c\"mTa9Lj7KUN\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:random_binary_from_chars/2\n\n[source,erlang]\n----\nuef_bin:random_binary_from_chars(Length, Chars) -\u003e RandomCharsBinary.\n----\n\nGenerates and returns a binary of size `Length` which consists of the given characters `Chars`.\n\n*Example:*\n\n[source,erlang]\n----\n\u003e uef_bin:random_binary_from_chars(16, \u003c\u003c\"ErlangForever\"\u003e\u003e).\n\u003c\u003c\"eFveerorreravgng\"\u003e\u003e\n----\n\n'''\n\n==== uef_bin:numeric_prefix/1\n\n[source,erlang]\n----\nuef_bin:numeric_prefix(Binary) -\u003e DigitsOnlyOrEmptyBinary.\n----\n\nReturns new binary `DigitsOnlyBinary` which consists of digits [0-9] wich are at the beginning in the given binary `Binary`. If `Binary` does not begin with digit, this function returns empty binary (`\u003c\u003c\u003e\u003e`).\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:numeric_prefix(\u003c\u003c\"3456sld1knskjd\"\u003e\u003e).\n\u003c\u003c\"3456\"\u003e\u003e\n\n\u003e uef_bin:numeric_prefix(\u003c\u003c\"ddd3456sld1knskjd\"\u003e\u003e).\n\u003c\u003c\u003e\u003e\n----\n\n'''\n\n==== uef_bin:strip_left/2\n\n[source,erlang]\n----\nuef_bin:strip_left(Binary1, Chars) -\u003e Binary2.\n----\n\n**Types:**\n[source,erlang]\n----\nBinary1 :: binary().\nChars :: binary() | integer().\nBinary2 :: binary().\n----\n\nRemoves leading `Chars` from `Binary1` and returns `Binary2`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:strip_left(\u003c\u003c\"www.example.com\"\u003e\u003e, \u003c\u003c\"w\"\u003e\u003e).\n\u003c\u003c\".example.com\"\u003e\u003e\n\n\u003e uef_bin:strip_left(\u003c\u003c\"www.example.com\"\u003e\u003e, \u003c\u003c\"ww\"\u003e\u003e).\n\u003c\u003c\"w.example.com\"\u003e\u003e\n\n\u003e uef_bin:strip_left(\u003c\u003c11, 11, 11, 12, 13, 14\u003e\u003e, 11).\n\u003c\u003c12,13,14\u003e\u003e\n\n\u003e uef_bin:strip_left(\u003c\u003c\"ААААБВГДЕЁЖ\"/utf8\u003e\u003e, \u003c\u003c\"А\"/utf8\u003e\u003e) =:= \u003c\u003c\"БВГДЕЁЖ\"/utf8\u003e\u003e.\ntrue\n\n\u003e uef_bin:strip_left(\u003c\u003c\"這這這這條街\"/utf8\u003e\u003e, \u003c\u003c\"這\"/utf8\u003e\u003e) =:= \u003c\u003c\"條街\"/utf8\u003e\u003e.\ntrue\n----\n\n'''\n\n==== uef_bin:strip_right/2\n\n[source,erlang]\n----\nuef_bin:strip_right(Binary1, Chars) -\u003e Binary2.\n----\n\n**Types:**\n[source,erlang]\n----\nBinary1 :: binary().\nChars :: binary() | integer().\nBinary2 :: binary().\n----\n\nRemoves trailing `Chars` from `Binary1` and returns `Binary2`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:strip_right(\u003c\u003c\"example.comwww\"\u003e\u003e, \u003c\u003c\"w\"\u003e\u003e).\n\u003c\u003c\"example.com\"\u003e\u003e\n\n\u003e uef_bin:strip_right(\u003c\u003c\"example.comwww\"\u003e\u003e, \u003c\u003c\"ww\"\u003e\u003e).\n\u003c\u003c\"example.comw\"\u003e\u003e\n\n\u003e uef_bin:strip_right(\u003c\u003c1, 2, 3, 4, 5, 5, 5\u003e\u003e, 5).\n\u003c\u003c1,2,3,4\u003e\u003e\n\n\u003e uef_bin:strip_right(\u003c\u003c\"АБВГДЕЁЖЖЖЖ\"/utf8\u003e\u003e, \u003c\u003c\"Ж\"/utf8\u003e\u003e) =:= \u003c\u003c\"АБВГДЕЁ\"/utf8\u003e\u003e.\ntrue\n\n\u003e uef_bin:strip_right(\u003c\u003c\"這條街街街街\"/utf8\u003e\u003e, \u003c\u003c\"街\"/utf8\u003e\u003e) =:= \u003c\u003c\"這條\"/utf8\u003e\u003e.\ntrue\n----\n\n'''\n\n==== uef_bin:strip_both/2\n\n[source,erlang]\n----\nuef_bin:strip_both(Binary1, Chars) -\u003e Binary2.\n----\n\n**Types:**\n[source,erlang]\n----\nBinary1 :: binary().\nChars :: binary() | integer().\nBinary2 :: binary().\n----\n\nRemoves leading and trailing `Chars` from `Binary1` and returns `Binary2`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_bin:strip_both(\u003c\u003c\"www.example.www\"\u003e\u003e, \u003c\u003c\"w\"\u003e\u003e).\n\u003c\u003c\".example.\"\u003e\u003e\n\n\u003e uef_bin:strip_both(\u003c\u003c\"com.example.com\"\u003e\u003e, \u003c\u003c\"com\"\u003e\u003e).\n\u003c\u003c\".example.\"\u003e\u003e\n\n\u003e uef_bin:strip_both(\u003c\u003c5,5,5, 1,2,3,4, 5,5,5\u003e\u003e, 5).\n\u003c\u003c1,2,3,4\u003e\u003e\n\n\u003e uef_bin:strip_both(\u003c\u003c\"ЖЖЖЖАБВГДЕЁЖЖЖЖ\"/utf8\u003e\u003e, \u003c\u003c\"Ж\"/utf8\u003e\u003e) =:= \u003c\u003c\"АБВГДЕЁ\"/utf8\u003e\u003e.\ntrue\n\n\u003e uef_bin:strip_both(\u003c\u003c\"街街街街這條街街街街\"/utf8\u003e\u003e, \u003c\u003c\"街\"/utf8\u003e\u003e) =:= \u003c\u003c\"這條\"/utf8\u003e\u003e.\ntrue\n----\n\n'''\n\n=== Module `uef_crypt`\n\n'''\n\n==== uef_crypt:md5_hex/1\n\n[source,erlang]\n----\nuef_crypt:md5_hex(IoData) -\u003e Binary.\n----\n\nReturns binary `Binary` in hexadecimal form of md5 hash of the argument `IoData`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_crypt:md5_hex(\"abcd\").\n\u003c\u003c\"e2fc714c4727ee9395f324cd2e7f331f\"\u003e\u003e\n\n\u003e uef_crypt:md5_hex(\u003c\u003c\"привет\"/utf8\u003e\u003e).\n\u003c\u003c\"608333adc72f545078ede3aad71bfe74\"\u003e\u003e\n\n\u003e uef_crypt:md5_hex([\"how\", [\"is\", [\"it\"]], \"going\", $?]).\n\u003c\u003c\"eb89df06495cef83e3ec185aefe81d0e\"\u003e\u003e\n----\n\n'''\n\n=== Module `uef_encode`\n\n'''\n\n==== uef_encode:html_encode_bin/1\n\n[source,erlang]\n----\nuef_encode:html_encode_bin(Html) -\u003e EncodedBinary.\n----\n\nTakes argument `Html`, replaces some unsafe symbols with their appropriate HTML entities and returns binary.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_encode:html_encode_bin(\"\u003c\u003e\u0026©\\n™\").\n\u003c\u003c\"\u0026lt;\u0026gt;\u0026amp;\u0026copy;\u003cbr/\u003e\u0026trade;\"\u003e\u003e\n\n\u003e uef_encode:html_encode_bin(\"♦±Σ\").\n\u003c\u003c\"\u0026#9830;\u0026plusmn;\u0026Sigma;\"\u003e\u003e\n----\n\n'''\n\n==== uef_encode:html_encode_list/1\n\n[source,erlang]\n----\nuef_encode:html_encode_list(Html) -\u003e EncodedList.\n----\n\nTakes argument Html, replaces some unsafe symbols with their appropriate HTML entities and returns list of binaries.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_encode:html_encode_list(\"\u003c\u003e\u0026©\\n™\").\n[\u003c\u003c\"\u0026lt;\"\u003e\u003e,\u003c\u003c\"\u0026gt;\"\u003e\u003e,\u003c\u003c\"\u0026amp;\"\u003e\u003e,\u003c\u003c\"\u0026copy;\"\u003e\u003e,\u003c\u003c\"\u003cbr/\u003e\"\u003e\u003e,\u003c\u003c\"\u0026trade;\"\u003e\u003e]\n\n\u003e uef_encode:html_encode_list(\"♦±Σ\").\n[\u003c\u003c\"\u0026#9830;\"\u003e\u003e,\u003c\u003c\"\u0026plusmn;\"\u003e\u003e,\u003c\u003c\"\u0026Sigma;\"\u003e\u003e]\n----\n\n'''\n\n==== uef_encode:win_to_utf8/1\n\n[source,erlang]\n----\nuef_encode:win_to_utf8(Binary1251) -\u003e BinaryUtf8.\n----\n\nConverts *cp1251* binary to *utf-8* binary.\n\n*Example:*\n\n[source,erlang]\n----\nfile_1251_to_utf8() -\u003e\n    File1251 = \"1251.txt\",\n    FileUtf8 = \"utf8.txt\",\n    {ok, Bin1251} = file:read_file(File1251),\n    BinUtf8 = uef_encode:win_to_utf8(Bin1251), %converting\n    file:write_file(FileUtf8, BinUtf8).\n----\n\n'''\n\n=== Module `uef_file`\n\n---\n\n==== uef_file:read_file_info_fast/1\n\n[source,erlang]\n----\nuef_file:read_file_info_fast(Filename) -\u003e {ok, FileInfo} | {error, Reason}.\n----\n\nRetrieves information about **local** file. Returns `{ok, FileInfo}` if successful, otherwise `{error, Reason}`. Works as http://erlang.org/doc/man/file.html#read_file_info-2[file:read_file_info/2] but optimized for **local** files. This is a wrapper of:\n\n`file:read_file_info(Filename, [raw, {time, posix}])`.\n\n'''\n\n==== uef_file:read_file_fast/1\n\n[source,erlang]\n----\nuef_file:read_file_fast(Filename) -\u003e {ok, BinaryData} | {error, Reason}.\n----\n\nReads contents of **local** file `Filename` and returns `{ok, BinaryData}`, where `BinaryData` is a binary data object that contains the contents of `Filename`, or `{error, Reason}` if an error occurs. This function is optimized for reading contents of **local** files, as no Erlang process is used. It calls http://erlang.org/doc/man/file.html#open-2[file:open/2] with options `[read, raw, binary]`.\n\n'''\n\n=== Module `uef_format`\n\n'''\n\n==== uef_format:format_bytes/1\n\n[source,erlang]\n----\nuef_format:format_bytes(Bytes) -\u003e FormattedBytes.\n----\n\nThe same as `uef_format:format_bytes(Bytes, #{})`. See link:#uef_formatformat_bytes2[uef_format:format_bytes/2] docs.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_bytes(1024).\n\u003c\u003c\"1KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1000).\n\u003c\u003c\"0KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576).\n\u003c\u003c\"1MB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(10485760).\n\u003c\u003c\"10MB\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_bytes/2\n\n[source,erlang]\n----\nuef_format:format_bytes(Bytes, Options) -\u003e FormattedBytes.\n----\n\n**Types:**\n\n[source,erlang]\n----\nBytes :: integer().\n\nOptions :: #{\n    units =\u003e Units,\n    base =\u003e Base,\n    to_type =\u003e ToType,\n    sep =\u003e Separator\n}.\n\nUnits :: auto | MultiUnits.\nMultiUnits :: 'KB' | 'MB' | 'GB' | 'TB' | 'PB' | 'EB' | 'ZB' | 'YB'.\nBase :: 2 | 10.\nToType :: bin | int.\nSeparator :: binary().\n\nFormattedBytes :: binary() | integer() | {integer(), MultiUnits}.\n----\n\nDefault `Options`:\n\n[source,erlang]\n----\n#{ units =\u003e auto, base =\u003e 2, to_type =\u003e bin, sep =\u003e \u003c\u003c\u003e\u003e }.\n----\n\nConverts bytes `Bytes` to https://en.wikipedia.org/wiki/Megabyte[multiples of bytes]. The datatype of the return value depends on `ToType` and `Units`:\n\n* if `ToType` is `bin`, it returns `binary()`;\n* if `ToType` is `int`, it returns `integer()`;\n* if `ToType` is `int` and `Units` is `auto`, tuple `{integer(), MultiUnits}` is returned.\n\nThe value of `Base` affects the conversion of `Bytes` to multiples:\n\n* `Base = 2` means that `1KB = 1024 bytes`, `1MB = 1048576 bytes`, ...;\n* `Base = 10` means that `1KB = 1000 bytes`, `1MB = 1000000 bytes`, ...\n\nIf the value of `Units` is `auto`, bytes are converted to the most reasonable multiples of bytes.\n\n`Separator` is a separator between _integer value_ and `Units`. This option affects the result when `ToType` is `bin`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_bytes(1000000, #{units =\u003e auto, base =\u003e 2}).\n\u003c\u003c\"976KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e auto, base =\u003e 2}).\n\u003c\u003c\"1MB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e 'KB', base =\u003e 2}).\n\u003c\u003c\"1024KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e 'KB', base =\u003e 10}).\n\u003c\u003c\"1048KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e auto, base =\u003e 2, to_type =\u003e int}).\n{1,'MB'}\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e 'KB', base =\u003e 2, to_type =\u003e int}).\n1024\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e 'KB', to_type =\u003e bin, sep =\u003e \u003c\u003c\" \"\u003e\u003e}).\n\u003c\u003c\"1024 KB\"\u003e\u003e\n\n\u003e uef_format:format_bytes(1048576, #{units =\u003e 'KB', to_type =\u003e bin, sep =\u003e \u003c\u003c\"|\"\u003e\u003e}).\n\u003c\u003c\"1024|KB\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_number/3\n\n[source,erlang]\n----\nuef_format:format_number(Number, Precision, Decimals) -\u003e FormattedNumber.\n----\n\nThe same as `uef_format:format_number/4` with `#{}` as the forth argument. See link:#uef_formatformat_number4[uef_format:format_number/4] docs.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_number(199.4567, 2, 3).\n\u003c\u003c\"199.460\"\u003e\u003e\n\n\u003euef_format:format_number(199.4567, 1, 3).\n\u003c\u003c\"199.500\"\u003e\u003e\n\n\u003e uef_format:format_number(199.4567, 0, 4).\n\u003c\u003c\"199.0000\"\u003e\u003e\n\n\u003e uef_format:format_number(199.4567, -1, 2).\n\u003c\u003c\"200.00\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_number/4\n\n[source,erlang]\n----\nuef_format:format_number(Number, Precision, Decimals, Options) -\u003e FormattedNumber.\n----\n\nFormats `Number` by adding thousands separator between each set of 3 digits to the left of the decimal point, substituting `Decimals` for the decimal point, and rounding to the specified `Precision`. Returns a **binary** value.\n\n**Types:**\n\n[source,erlang]\n----\nNumber :: number().\nPrecision :: integer().\nDecimals :: non_neg_integer().\nFormattedNumber :: binary().\n----\n\n`Options` is a map:\n\n[source,erlang]\n----\n#{\n    thousands_sep =\u003e binary() | string(), % Thousands separator\n    decimal_point =\u003e binary() | string(), % Decimal point\n    cur_symbol =\u003e binary() | string(), %% Currency symbol\n    cur_pos =\u003e 'left' | 'right', % Currency position against price (left or right)\n    cur_sep =\u003e binary() | string() % Separator between currency and price\n}\n----\n\n**Note:** to get maximum performance use **binary** values for options `thousands_sep`, `decimal_point`, `cur_symbol` and `cur_sep` instead of strings.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_number(1234567890.4567, 2, 2, #{}).\n\u003c\u003c\"1234567890.46\"\u003e\u003e\n\n\u003e uef_format:format_number(1234567890.4567, 2, 2, #{thousands_sep =\u003e \",\", cur_symbol =\u003e \"$\"}).\n\u003c\u003c\"$1,234,567,890.46\"\u003e\u003e\n\n\u003e uef_format:format_number(1234567890.4567, 2, 2, #{\n    thousands_sep =\u003e \",\",\n    cur_symbol =\u003e \"USD\",\n    cur_sep =\u003e \" \", % whitespace\n    cur_pos =\u003e right}).\n\u003c\u003c\"1,234,567,890.46 USD\"\u003e\u003e\n\n\u003e uef_format:format_number(1234567890.4567, 2, 4, #{\n    thousands_sep =\u003e \",\",\n    decimal_point =\u003e \"==\",\n    cur_symbol =\u003e \"USD\",\n    cur_sep =\u003e \" \",\n    cur_pos =\u003e left}).\n\u003c\u003c\"USD 1,234,567,890==4600\"\u003e\u003e\n\n\u003e uef_format:format_number(1234567890.4567, 2, 4, #{\n    thousands_sep =\u003e \u003c\u003c\",\"\u003e\u003e, % binary()\n    decimal_point =\u003e \u003c\u003c\".\"\u003e\u003e, % binary()\n    cur_symbol =\u003e \u003c\u003c\"USD\"\u003e\u003e, % binary()\n    cur_sep =\u003e \u003c\u003c\" \"\u003e\u003e, % binary()\n    cur_pos =\u003e left}).\n\u003c\u003c\"USD 1,234,567,890.4600\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_price/1\n\n[source,erlang]\n----\nuef_format:format_price(Number) -\u003e FormattedPrice.\n----\n\nFormats `Number` in price-like style. Returns a binary containing `FormattedPrice` formatted with a precision of `2` and decimal digits of `2`.\n\nThe same as `uef_format:format_price/2` with a precision of `2` as the second argument. See link:#uef_formatformat_price2[uef_format:format_price/2] docs.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_price(199).\n\u003c\u003c\"199.00\"\u003e\u003e\n\n\u003e uef_format:format_price(199.9876).\n\u003c\u003c\"199.99\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_price/2\n\n[source,erlang]\n----\nuef_format:format_price(Number, Precision) -\u003e FormattedPrice.\n----\n\nFormats `Number` in price-like style. Returns a binary containing `FormattedPrice` formatted with a specified precision as the second argument and decimal digits of `2`.\n\nThe same as `uef_format:format_price/3` with `#{}` as the third argument. See link:#uef_formatformat_price3[uef_format:format_price/3] docs.\n\n*Example:*\n\n[source,erlang]\n----\n\u003e uef_format:format_price(1999.9876, 4).\n\u003c\u003c\"1999.99\"\u003e\u003e\n----\n\n'''\n\n==== uef_format:format_price/3\n\n[source,erlang]\n----\nuef_format:format_price(Number, Precision, CurrencySymbol_OR_Options) -\u003e FormattedPrice.\n----\n\nFormats `Number` in price-like style. Returns a binary containing `FormattedPrice` formatted with a specified precision as the second argument, decimal digits of `2`, and with currency symbol (or options) as the third argument.\n\nIf `CurrencySymbol_OR_Options` is a `map` the functions works as link:#uef_formatformat_number4[uef_format:format_number/4] with decimal digits of `2` as the third argument and with options as the forth one.\n\nIf `CurrencySymbol_OR_Options` is a `binary` or a `string`, the corresponding currency symbol is added to the left.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_format:format_price(1000.8767, 4, #{}).\n\u003c\u003c\"1000.88\"\u003e\u003e\n\n\n\u003e uef_format:format_price(1000.8767, 4, #{\n    thousands_sep =\u003e \",\",\n    cur_symbol =\u003e \"USD\",\n    cur_sep =\u003e \" \",\n    cur_pos =\u003e right}).\n\u003c\u003c\"1,000.88 USD\"\u003e\u003e\n\n\n\u003e uef_format:format_price(1000.8767, 4, #{\n    thousands_sep =\u003e \",\",\n    cur_symbol =\u003e \u003c\u003c\"руб.\"/utf8\u003e\u003e,\n    cur_sep =\u003e \" \",\n    cur_pos =\u003e right}).\n\u003c\u003c49,44,48,48,48,46,56,56,32,209,128,209,131,208,177,46\u003e\u003e % \u003c\u003c\"1,000.88 руб.\"/utf8\u003e\u003e.\n\n\n\u003e uef_format:format_price(1000.8767, 4, \"$\").\n\u003c\u003c\"$1000.88\"\u003e\u003e\n\n\n\u003e uef_format:format_price(99.999, 2, \"$\").\n\u003c\u003c\"$100.00\"\u003e\u003e\n\n\n\u003e uef_format:format_price(99.99, 2, \"$\").\n\u003c\u003c\"$99.99\"\u003e\u003e\n\n\n\u003e uef_format:format_price(99.99, 2, \u003c\u003c\"€\"/utf8\u003e\u003e).\n\u003c\u003c226,130,172,57,57,46,57,57\u003e\u003e % \u003c\u003c\"€99.99\"/utf8\u003e\u003e\n\n----\n\n'''\n\n=== Module `uef_lists`\n\n'''\n\n==== uef_lists:split_list_into_chunks/2\n\n[source,erlang]\n----\nuef_lists:split_list_into_chunks(List, MaxLen) -\u003e [List1, List2, ..., ListN].\n----\n\nSplits `List` into list of lists `[List1, List2, ..., ListN]` where `List1, List2, ..., ListN` are lists with maximum `MaxLen` elements.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 1).\n[[1],[2],[3],[4],[5],[6],[7],[8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 2).\n[[1,2],[3,4],[5,6],[7,8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 3).\n[[1,2,3],[4,5,6],[7,8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 4).\n[[1,2,3,4],[5,6,7,8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 8).\n[[1,2,3,4,5,6,7,8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 9).\n[[1,2,3,4,5,6,7,8]]\n\n\u003e uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 99).\n[[1,2,3,4,5,6,7,8]]\n----\n\n'''\n\n==== uef_lists:lists_to_list_of_tuples/2\n\n[source,erlang]\n----\nuef_lists:lists_to_list_of_tuples(List1, List2) -\u003e List3.\n----\n\nTransforms two lists into one list of two-tuples, where the first element of each tuple is taken from the first list and the second element is taken from the second list one by one.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_lists:lists_to_list_of_tuples([a,b,c], [1,2]).\n[{a,1},{a,2},{b,1},{b,2},{c,1},{c,2}]\n\n\u003e uef_lists:lists_to_list_of_tuples([a,b,c], [1,2,3]).\n[{a,1},{a,2},{a,3},{b,1},{b,2},{b,3},{c,1},{c,2},{c,3}]\n----\n\n'''\n\n==== uef_lists:lists_to_list_of_tuples/3\n\n[source,erlang]\n----\nuef_lists:lists_to_list_of_tuples(List1, List2, List3) -\u003e List4.\n----\n\nTransforms three lists into one list of three-tuples, where the first element of each tuple is taken from the first list, the second element is taken from the second list one by one, and the third element is taken from the third list one by one.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_lists:lists_to_list_of_tuples([a1,b1], [a2,b2], [a3,b3]).\n[{a1,a2,a3},\n {a1,a2,b3},\n {a1,b2,a3},\n {a1,b2,b3},\n {b1,a2,a3},\n {b1,a2,b3},\n {b1,b2,a3},\n {b1,b2,b3}]\n\n\u003e uef_lists:lists_to_list_of_tuples([a1,b1], [a2,b2,c2], [a3,b3]).\n[{a1,a2,a3},\n {a1,a2,b3},\n {a1,b2,a3},\n {a1,b2,b3},\n {a1,c2,a3},\n {a1,c2,b3},\n {b1,a2,a3},\n {b1,a2,b3},\n {b1,b2,a3},\n {b1,b2,b3},\n {b1,c2,a3},\n {b1,c2,b3}]\n----\n\n'''\n\n==== uef_lists:search/2\n\n[source,erlang]\n----\nuef_lists:search(Pred, List) -\u003e {value, Value} | false.\n----\n\nIf there is a `Value` in `List` such that `Pred(Value)` returns `true`, returns `{value, Value}` for the first such `Value`, otherwise returns `false`.\n\n**Note:** Since OTP **21.0** use BIF `lists:search/2` instead.\n\n'''\n\n=== Module `uef_maps`\n\n'''\n\n==== uef_maps:delete_nested/2\n\n[source,erlang]\n----\nuef_maps:delete_nested(Keys, Map1) -\u003e {ok, Map2} | {error, {badkey, SomeKey}} | {error, empty_keys}.\n----\n\nSay, `Keys` is a list of elements `Key1, Key2, ..., KeyN` and `Map1` has internal structure `#{Key1 =\u003e #{Key2 =\u003e #{... =\u003e #{KeyN =\u003e ValueN}}}}`. The function removes key `KeyN`, if it exists, and its associated value from the corresponding internal map and updates the entire structure of map `Map1` getting new map `Map2`. There are three possible return values:\n\n* tuple `{ok, Map2}` if `KeyN` was removed;\n\n* tuple `{error, {badkey, SomeKey}}` if `SomeKey` does not exist in the structure of map `Map1`, where `SomeKey` is one of the elements of list `Keys`;\n\n* tuple `{error, empty_keys}` if `Keys` is empty list.\n\nThe call fails with a `{badmap,Map1}` exception if `Map1` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\nSee also: link:#uef_mapsremove_nested2[uef_maps:remove_nested/2], link:#uef_mapstake_nested2[uef_maps:take_nested/2].\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Map1 = #{1 =\u003e #{2 =\u003e #{3 =\u003e val3, 33 =\u003e val33}}}.\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}\n\n\u003e uef_maps:delete_nested([], Map1).\n{error,empty_keys}\n\n\u003e uef_maps:delete_nested([1], Map1).\n{ok,#{}}\n\n\u003e uef_maps:delete_nested([1,2], Map1).\n{ok,#{1 =\u003e #{}}}\n\n\u003e uef_maps:delete_nested([1,2,3], Map1).\n{ok,#{1 =\u003e #{2 =\u003e #{33 =\u003e val33}}}}\n\n\u003e uef_maps:delete_nested([-1], Map1).\n{error,{badkey,-1}}\n\n\u003e uef_maps:delete_nested([1,-2], Map1).\n{error,{badkey,-2}}\n\n\u003e uef_maps:delete_nested([1,2,-3], Map1).\n{error,{badkey,-3}}\n\n\u003e uef_maps:delete_nested([1,2,3,4], Map1).\n{error,{badkey,4}}\n\n\u003e uef_maps:delete_nested([1,2,3,4,5], Map1).\n{error,{badkey,4}} % 4, not 5!\n----\n\n'''\n\n==== uef_maps:find_nested/2\n\n[source,erlang]\n----\nuef_maps:find_nested(Keys, Map) -\u003e {ok, Value} | error.\n----\n\nTraverses nested map `Map` (*map of maps*) deep through the keys that are elements of list `Keys`. Returns tuple `{ok, Value}`, where `Value` is the value associated with the last element of list `Keys`, or `error` if no value is found.\n\nThe call fails with a `{badmap,Map}` exception if `Map` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Value = abc, M3 = #{key4 =\u003e Value}, M2 = #{key3 =\u003e M3}, M1 = #{key2 =\u003e M2}, M0 = #{key1 =\u003e M1}.\n#{key1 =\u003e #{key2 =\u003e #{key3 =\u003e #{key4 =\u003e abc}}}} % M0\n\n\u003e uef_maps:find_nested([key1], M0).\n{ok,#{key2 =\u003e #{key3 =\u003e #{key4 =\u003e abc}}}} % {ok, M1}\n\n\u003e uef_maps:find_nested([key1,key2], M0).\n{ok,#{key3 =\u003e #{key4 =\u003e abc}}} % {ok, M2}\n\n\u003e uef_maps:find_nested([key1,key2,key3], M0).\n{ok,#{key4 =\u003e abc}} % {ok, M3}\n\n\u003e uef_maps:find_nested([key1,key2,key3,key4], M0).\n{ok,abc} % {ok, Value}\n\n\u003e uef_maps:find_nested([-1], M0).\nerror\n\n\u003e uef_maps:find_nested([key1,key2,-3,key4], M0).\nerror\n\n\u003e uef_maps:find_nested([key1,key2,key3,-4], M0).\nerror\n\n\u003e uef_maps:find_nested([key1,key2,key3,key4,key5], M0).\n** exception error: {badmap,abc}\n----\n\n'''\n\n==== uef_maps:get_nested/2\n\n[source,erlang]\n----\nuef_maps:get_nested(Keys, Map) -\u003e Value.\n----\n\nTraverses nested map `Map` (*map of maps*) deep through the keys that are elements of list `Keys`. Returns value `Value` associated with the last element of list `Keys`.\n\nThe call fails with a `{badmap,Map}` exception if `Map` is not a map, or with a `{badkeys,Keys}` exception if no value is found, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Value = abc, M3 = #{key4 =\u003e Value}, M2 = #{key3 =\u003e M3}, M1 = #{key2 =\u003e M2}, M0 = #{key1 =\u003e M1}.\n#{key1 =\u003e #{key2 =\u003e #{key3 =\u003e #{key4 =\u003e abc}}}} % M0\n\n\u003e uef_maps:get_nested([key1], M0).\n#{key2 =\u003e #{key3 =\u003e #{key4 =\u003e abc}}} % M1\n\n\u003e uef_maps:get_nested([key1,key2], M0).\n#{key3 =\u003e #{key4 =\u003e abc}} % M2\n\n\u003e uef_maps:get_nested([key1,key2,key3], M0).\n#{key4 =\u003e abc} % M3\n\n\u003e uef_maps:get_nested([key1,key2,key3,key4], M0).\nabc % Value\n\n----\n\n'''\n\n==== uef_maps:get_nested/3\n\n[source,erlang]\n----\nuef_maps:get_nested(Keys, Map, Default) -\u003e Value | Default.\n----\n\nTraverses nested map `Map` (*map of maps*) deep through the keys that are elements of list `Keys`. Returns value `Value` associated with the last element of list `Keys`. If no value is found, `Default` is returned.\n\nThe call fails with a `{badmap,Map}` exception if `Map` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list. It **does not** fail if any internal value associated with any element of list `Keys` is not a map.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Value = abc, Default = default, M3 = #{key4 =\u003e Value}, M2 = #{key3 =\u003e M3}, M1 = #{key2 =\u003e M2}, M0 = #{key1 =\u003e M1}.\n#{key1 =\u003e #{key2 =\u003e #{key3 =\u003e #{key4 =\u003e abc}}}} % M0.\n\n\u003e uef_maps:get_nested([key1,key2,key3,key4], M0, Default).\nabc % Value\n\n\u003e uef_maps:get_nested([key1,key2,key3,-4], M0, Default).\ndefault % Default\n\n\u003e uef_maps:get_nested([key1,key2,-3,key4], M0, Default).\ndefault % Default\n\n\u003e uef_maps:get_nested([key1,key2,key3,key4,key5], M0, Default).\ndefault % Default anyway. Doesn't fail\n----\n\n'''\n\n==== uef_maps:is_key_nested/2\n\n[source,erlang]\n----\nuef_maps:is_key_nested(Keys, Map) -\u003e true | false.\n----\n\nReturns `true` if map `Map` contains submaps as values associated with their own key corresponding to the element of list `Keys`, and returns `false` otherwise.\n\nThe call fails with a `{badmap,Map}` exception if `Map` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e M3 = #{key4 =\u003e value}, M2 = #{key3 =\u003e M3}, M1 = #{key2 =\u003e M2}, M0 = #{key1 =\u003e M1}.\n#{key1 =\u003e #{key2 =\u003e #{key3 =\u003e #{key4 =\u003e value}}}} % M0\n\n\u003e uef_maps:is_key_nested([key1,key2,key3,key4], M0).\ntrue\n\n\u003e uef_maps:is_key_nested([key1,key2,key3], M0).\ntrue\n\n\u003e uef_maps:is_key_nested([key1,key2], M0).\ntrue\n\n\u003e uef_maps:is_key_nested([key1], M0).\ntrue\n\n\u003e uef_maps:is_key_nested([], M0).\nfalse\n\n\u003e uef_maps:is_key_nested([key1,key2,key3,key4,key5], M0).\nfalse\n\n\u003e uef_maps:is_key_nested([-1,key2,key3,key4], M0).\nfalse\n\n\u003e uef_maps:is_key_nested([key1,-2,key3,key4], M0).\nfalse\n----\n\n'''\n\n==== uef_maps:new_nested/1\n\n[source,erlang]\n----\nuef_maps:new_nested(Keys) -\u003e Map.\n----\n\nSame as `uef_maps:new_nested(Keys, #{})`. See docs of link:#uef_mapsnew_nested2[uef_maps:new_nested/2].\n\n'''\n\n==== uef_maps:new_nested/2\n\n[source,erlang]\n----\nuef_maps:new_nested(Keys, Value) -\u003e Map.\n----\n\nReturns new nested map `Map` with the deepest map `#{LastKey =\u003e Value}`, where `LastKey` is the last element of list `Keys`.\n\nThe call fails with a `{badlist,Keys}` exception if `Keys` is not a list.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_maps:new_nested([], value).\n#{}\n\n\u003e uef_maps:new_nested([key], value).\n#{key =\u003e value}\n\n\u003e uef_maps:new_nested([key1, key2], value).\n#{key1 =\u003e #{key2 =\u003e value}}\n\n\u003e uef_maps:new_nested([key1, key2, key3], value).\n#{key1 =\u003e #{key2 =\u003e #{key3 =\u003e value}}}\n----\n\n'''\n\n==== uef_maps:put_nested/3\n\n[source,erlang]\n----\nuef_maps:put_nested(Keys, Value, Map1) -\u003e Map2.\n----\n\nSay, `Keys` is a list of elements `Key1, Key2, ..., KeyN` and `Map1` has internal structure `#{Key1 =\u003e #{Key2 =\u003e #{... =\u003e #{KeyN =\u003e ValueN}}}}`. The function associates `KeyN` with value `Value` and updates the entire structure of map `Map1` returning new map `Map2`. If some keys from list `Keys` are not in the structure of map `Map1`, they will be inserted into the structure of map `Map2` in the same order.\n\nThe call fails with a `{badmap,Map1}` exception if `Map1` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\nSee also: link:#uef_mapsupdate_nested3[uef_maps:update_nested/3].\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Map1 = #{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}}.\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}} % Map1\n\n\u003e uef_maps:put_nested([], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}} % Map1 (empty list of keys)\n\n\u003e uef_maps:put_nested([1], new_value, Map1).\n#{1 =\u003e new_value}\n\n\u003e uef_maps:put_nested([1,2], new_value, Map1).\n#{1 =\u003e #{2 =\u003e new_value}}\n\n\u003e uef_maps:put_nested([1,2,3], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e new_value}}}\n\n\u003e uef_maps:put_nested([1,2,-3], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{-3 =\u003e new_value,3 =\u003e val3}}}\n\n\u003e uef_maps:put_nested([1,2,3,4], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e #{4 =\u003e new_value}}}}\n\n\u003e uef_maps:put_nested([-1], new_value, Map1).\n#{-1 =\u003e new_value,1 =\u003e #{2 =\u003e #{3 =\u003e val3}}}\n\n\u003e uef_maps:put_nested([1,-2], new_value, Map1).\n#{1 =\u003e #{-2 =\u003e new_value,2 =\u003e #{3 =\u003e val3}}}\n\n\u003e uef_maps:put_nested([1,2,-3], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{-3 =\u003e new_value,3 =\u003e val3}}}\n\n\u003e uef_maps:put_nested([1,2,3,-4], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e #{-4 =\u003e new_value}}}}\n----\n\n'''\n\n==== uef_maps:remove_nested/2\n\n[source,erlang]\n----\nuef_maps:remove_nested(Keys, Map1) -\u003e Map2.\n----\n\nSay, `Keys` is a list of elements `Key1, Key2, ..., KeyN` and `Map1` has internal structure `#{Key1 =\u003e #{Key2 =\u003e #{... =\u003e #{KeyN =\u003e ValueN}}}}`. The function removes key `KeyN`, if it exists, and its associated value from the corresponding internal map and updates the entire structure of map `Map1` returning new map `Map2`. If some keys from list `Keys` are not in the structure of map `Map1` the function returns a map without changes.\n\nThe call fails with a `{badmap,Map1}` exception if `Map1` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\nSee also: link:#uef_mapsdelete_nested2[uef_maps:delete_nested/2], link:#uef_mapstake_nested2[uef_maps:take_nested/2].\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Map1 = #{1 =\u003e #{2 =\u003e #{3 =\u003e val3, 33 =\u003e val33}}}.\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}\n\n\u003e uef_maps:remove_nested([], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1 (empty list of keys)\n\n\u003e uef_maps:remove_nested([1], Map1).\n#{}\n\n\u003e uef_maps:remove_nested([1,2], Map1).\n#{1 =\u003e #{}}\n\n\u003e uef_maps:remove_nested([1,2,3], Map1).\n#{1 =\u003e #{2 =\u003e #{33 =\u003e val33}}}\n\n\u003e uef_maps:remove_nested([-1], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1\n\n\u003e uef_maps:remove_nested([1,-2], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1\n\n\u003e uef_maps:remove_nested([1,2,-3], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1\n\n\u003e uef_maps:remove_nested([1,2,3,4], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1\n\n\u003e uef_maps:remove_nested([1,2,3,4,5], Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}  % Map1\n----\n\n'''\n\n==== uef_maps:take_nested/2\n\n[source,erlang]\n----\nuef_maps:take_nested(Keys, Map1) -\u003e {Value, Map2} | error.\n----\n\nSay, `Keys` is a list of elements `Key1, Key2, ..., KeyN` and `Map1` has internal structure `#{Key1 =\u003e #{Key2 =\u003e #{... =\u003e #{KeyN =\u003e Value}}}}`. The function removes key `KeyN`, if it exists, and its associated value `Value` from the corresponding internal map and updates the entire structure of map `Map1` returning tuple `{Value, Map2}`. If some keys from list `Keys` are not in the structure of map `Map1` the function returns `error`.\n\nThe call fails with a `{badmap,Map1}` exception if `Map1` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\nSee also: link:#uef_mapsdelete_nested2[uef_maps:delete_nested/2], link:#uef_mapsremove_nested2[uef_maps:remove_nested/2].\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Map1 = #{1 =\u003e #{2 =\u003e #{3 =\u003e val3, 33 =\u003e val33}}}.\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}}}\n\n\u003e uef_maps:take_nested([], Map1).\nerror\n\n\u003e uef_maps:take_nested([1], Map1).\n{#{2 =\u003e #{3 =\u003e val3,33 =\u003e val33}},#{}}\n\n\u003e uef_maps:take_nested([1,2], Map1).\n{#{3 =\u003e val3,33 =\u003e val33},#{1 =\u003e #{}}}\n\n\u003e uef_maps:take_nested([1,2,3], Map1).\n{val3,#{1 =\u003e #{2 =\u003e #{33 =\u003e val33}}}}\n\n\u003e uef_maps:take_nested([-1], Map1).\nerror\n\n\u003e uef_maps:take_nested([1,-2], Map1).\nerror\n\n\u003e uef_maps:take_nested([1,2,-3], Map1).\nerror\n\n\u003e uef_maps:take_nested([1,2,3,4], Map1).\nerror\n\n\u003e uef_maps:take_nested([1,2,3,4,5], Map1).\nerror\n----\n\n'''\n\n==== uef_maps:update_nested/3\n\n[source,erlang]\n----\nuef_maps:update_nested(Keys, Value, Map1) -\u003e Map2.\n----\n\nWorks similar to link:#uef_mapsput_nested3[uef_maps:put_nested/3] with the difference that it fails with a `{badkey,SomeKey}` exception if `SomeKey` does not exist in the structure of map `Map1`, where `SomeKey` is one of the elements of list `Keys`.\n\nThe call also fails with a `{badmap,Map1}` exception if `Map1` is not a map, or with a `{badlist,Keys}` exception if `Keys` is not a list.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e Map1 = #{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}}.\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}} % Map1\n\n\u003e uef_maps:update_nested([], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e val3}}} % Map1 (empty list of keys)\n\n\u003e uef_maps:update_nested([1], new_value, Map1).\n#{1 =\u003e new_value}\n\n\u003e uef_maps:update_nested([1,2], new_value, Map1).\n#{1 =\u003e #{2 =\u003e new_value}}\n\n\u003e uef_maps:update_nested([1,2,3], new_value, Map1).\n#{1 =\u003e #{2 =\u003e #{3 =\u003e new_value}}}\n\n\u003e uef_maps:update_nested([1,2,3,4], new_value, Map1).\n** exception error: {badkey,4}\n\n\u003e uef_maps:update_nested([1,2,3,4,5], new_value, Map1).\n** exception error: {badkey,4} % 4, not 5! because 4 is before\n\n\u003e uef_maps:update_nested([-1], new_value, Map1).\n** exception error: {badkey,-1}\n\n\u003e uef_maps:update_nested([1,-2], new_value, Map1).\n** exception error: {badkey,-2}\n\n\u003e uef_maps:update_nested([1,2,-3], new_value, Map1).\n** exception error: {badkey,-3}\n\n\u003e uef_maps:update_nested([1,2,3,-4], new_value, Map1).\n** exception error: {badkey,-4}\n----\n\n'''\n\n=== Module `uef_num`\n\n'''\n\n==== uef_num:ctz/1\n\n[source,erlang]\n----\nuef_num:ctz(Integer) -\u003e TrailingZeros.\n----\n\nCounts https://en.wikipedia.org/wiki/Find_first_set[trailing zeros] in the binary representation of a positive integer. Returns the number of zero bits following the least significant one bit.\n\nThe call fails with a `{badarg,Integer}` exception if `Integer` is not a positive integer.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_num:ctz(2#10001000).\n3\n\n\u003e uef_num:ctz(7).\n0\n\n\u003e uef_num:ctz(2#00101010).\n1\n\n\u003e uef_num:ctz(2#1000000000000000000000000000000000000000000000000000000000000000).\n63\n\n\u003e uef_num:ctz(2#1111111111111111111111111111111111111111111111111111111111111111).\n0\n\n\u003e uef_num:ctz(16#FFFFFFFFFFFFFFFF).\n0\n----\n\n'''\n\n==== uef_num:lsb_pos/1\n\n[source,erlang]\n----\nuef_num:lsb_pos(Integer) -\u003e Position.\n----\n\nReturns the position of the https://en.wikipedia.org/wiki/Bit_numbering[least significant bit] (**LSB**) in the binary representation of a positive integer.\n\nThe call fails with a `{badarg,Integer}` exception if `Integer` is not a positive integer.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_num:lsb_pos(2#10001000).\n4\n\n\u003e uef_num:lsb_pos(7).\n1\n\n\u003e uef_num:lsb_pos(2#00101010).\n2\n\n\u003e uef_num:lsb_pos(2#1000000000000000000000000000000000000000000000000000000000000000).\n64\n\n\u003e uef_num:lsb_pos(2#1111111111111111111111111111111111111111111111111111111111111111).\n1\n\n\u003e uef_num:lsb_pos(16#FFFFFFFFFFFFFFFF).\n1\n----\n\n'''\n\n==== uef_num:msb_pos/1\n\n[source,erlang]\n----\nuef_num:msb_pos(Integer) -\u003e Position.\n----\n\nReturns the position of the https://en.wikipedia.org/wiki/Bit_numbering[most significant bit] (**MSB**) in the binary representation of a positive integer.\n\nThe call fails with a `{badarg,Integer}` exception if `Integer` is not a positive integer.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_num:msb_pos(2#111).\n3\n\n\u003e uef_num:msb_pos(7).\n3\n\n\u003e uef_num:msb_pos(2#0010101).\n5\n\n\u003e uef_num:msb_pos(2#1000000000000000000000000000000000000000000000000000000000000000).\n64\n\n\u003e uef_num:msb_pos(2#1111111111111111111111111111111111111111111111111111111111111111).\n64\n\n\u003e uef_num:msb_pos(16#FFFFFFFFFFFFFFFF).\n64\n----\n\n'''\n\n==== uef_num:popcount/1\n\n[source,erlang]\n----\nuef_num:popcount(Integer) -\u003e OneBits.\n----\n\nReturns the number of 1's (ones or one-bits) in the https://en.wikipedia.org/wiki/Binary_number#Representation[binary representation] of a non-negative integer.\nAlso known as population count, pop count, popcount, sideways sum, bit summation,\nor https://en.wikipedia.org/wiki/Hamming_weight[Hamming weight].\n\nThe call fails with a `{badarg,Integer}` exception if `Integer` is not a non-negative integer.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_num:popcount(7).\n3\n\n\u003e uef_num:popcount(0).\n0\n\n\u003e uef_num:popcount(2#1010101).\n4\n\n\u003e uef_num:popcount(2#1000000000000000000000000000000000000000000000000000000000000000).\n1\n\n\u003e uef_num:popcount(2#1111111111111111111111111111111111111111111111111111111111111111).\n64\n\n\u003e uef_num:popcount(16#FFFFFFFFFFFFFFFF).\n64\n----\n\n'''\n\n==== uef_num:round_number/2\n\n[source,erlang]\n----\nuef_num:round_number(Number, Precision) -\u003e Float.\n----\n\nRounds the number to the specified precision.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_num:round_number(10, 2).\n10.0\n\n\u003e uef_num:round_number(123.786, 2).\n123.79\n----\n\n'''\n\n==== uef_num:round_price/1\n\n[source,erlang]\n----\nuef_num:round_price(Number) -\u003e Float.\n----\n\nRounds the number to the precision of **2**. The same as `uef_num:round_number(Number, 2)`.\n\n'''\n\n=== Module `uef_time`\n\n'''\n\n==== uef_time:add_seconds/1\n\n[source,erlang]\n----\nuef_time:add_seconds(Seconds) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_seconds(erlang:localtime(), Seconds)`. See docs of link:#uef_timeadd_seconds2[uef_time:add_seconds/2].\n\n**Types:**\n\n[source,erlang]\n----\nSeconds :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_seconds/2\n\n[source,erlang]\n----\nuef_time:add_seconds(DateOrDatetime, Seconds) -\u003e NewDateTime.\n----\n\nAdds the number of seconds `Seconds` to `DateOrDatetime` and returns a new datetime value.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nSeconds :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_seconds({2019, 1, 1}, 10).\n{{2019,1,1},{0,0,10}}\n\n\u003e uef_time:add_seconds({2019, 1, 1}, -10).\n{{2018,12,31},{23,59,50}}\n\n\u003e uef_time:add_seconds({{2019, 1, 1}, {23, 59, 0}}, 10).\n{{2019,1,1},{23,59,10}}\n\n\u003e uef_time:add_seconds({{2019, 1, 1}, {23, 59, 0}}, -10).\n{{2019,1,1},{23,58,50}}\n----\n\n'''\n\n==== uef_time:add_minutes/1\n\n[source,erlang]\n----\nuef_time:add_minutes(Minutes) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_seconds(Minutes * 60)`. See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].\n\n**Types:**\n\n[source,erlang]\n----\nMinutes :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_minutes/2\n\n[source,erlang]\n----\nuef_time:add_minutes(DateOrDatetime, Minutes) -\u003e NewDateTime.\n----\n\nAdds the number of minutes `Minutes` to `DateOrDatetime` and returns a new datetime value.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nMinutes :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_minutes({2019, 1, 1}, 10).\n{{2019,1,1},{0,10,0}}\n\n\u003e uef_time:add_minutes({2019, 1, 1}, -10).\n{{2018,12,31},{23,50,0}}\n\n\u003e uef_time:add_minutes({{2019, 1, 1}, {23, 59, 0}}, 10).\n{{2019,1,2},{0,9,0}}\n\n\u003e uef_time:add_minutes({{2019, 1, 1}, {0, 1, 0}}, -10).\n{{2018,12,31},{23,51,0}}\n----\n\n'''\n\n==== uef_time:add_hours/1\n\n[source,erlang]\n----\nuef_time:add_hours(Hours) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_seconds(Hours * 3600)`. See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].\n\n**Types:**\n\n[source,erlang]\n----\nHours :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_hours/2\n\n[source,erlang]\n----\nuef_time:add_hours(DateOrDatetime, Hours) -\u003e NewDateTime.\n----\n\nAdds the number of hours `Hours` to `DateOrDatetime` and returns a new datetime value.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nHours :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_hours({2019, 1, 1}, 10).\n{{2019,1,1},{10,0,0}}\n\n\u003e uef_time:add_hours({2019, 1, 1}, -10).\n{{2018,12,31},{14,0,0}}\n\n\u003e uef_time:add_hours({{2019, 1, 1}, {23, 59, 0}}, 10).\n{{2019,1,2},{9,59,0}}\n\n\u003e uef_time:add_hours({{2019, 1, 1}, {0, 1, 0}}, -10).\n{{2018,12,31},{14,1,0}}\n----\n\n'''\n\n==== uef_time:add_days/1\n\n[source,erlang]\n----\nuef_time:add_days(Days) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_seconds(Days * 86400)`. See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].\n\n**Types:**\n\n[source,erlang]\n----\nDays :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_days/2\n\n[source,erlang]\n----\nuef_time:add_days(DateOrDatetime, Days) -\u003e NewDateOrDateTime.\n----\n\nAdds the number of days `Days` to `DateOrDatetime` and returns a new *date or datetime* value. The type of `NewDateOrDateTime` is the same as the type of `DateOrDatetime`.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nDays :: integer().\nNewDateOrDateTime :: calendar:date() | calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_days({2019, 1, 1}, 10).\n{2019,1,11}\n\n\u003e uef_time:add_days({2019, 1, 1}, -10).\n{2018,12,22}\n\n\u003e uef_time:add_days({{2019, 1, 1}, {23, 59, 0}}, 10).\n{{2019,1,11},{23,59,0}}\n\n\u003e uef_time:add_days({{2019, 1, 1}, {0, 1, 0}}, -10).\n{{2018,12,22},{0,1,0}}\n----\n\n'''\n\n==== uef_time:add_weeks/1\n\n[source,erlang]\n----\nuef_time:add_weeks(Weeks) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_seconds(Weeks * 604800)`. See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].\n\n**Types:**\n\n[source,erlang]\n----\nWeeks :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_weeks/2\n\n[source,erlang]\n----\nuef_time:add_weeks(DateOrDatetime, Weeks) -\u003e NewDateOrDateTime.\n----\n\nAdds the number of weeks `Weeks` to `DateOrDatetime` and returns a new *date or datetime* value. The type of `NewDateOrDateTime` is the same as the type of `DateOrDatetime`.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nWeeks :: integer().\nNewDateOrDateTime :: calendar:date() | calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_weeks({2019, 1, 1}, 4).\n{2019,1,29}\n\n\u003e uef_time:add_weeks({2019, 1, 1}, -4).\n{2018,12,4}\n\n\u003e uef_time:add_weeks({{2019, 1, 1}, {23, 59, 0}}, 4).\n{{2019,1,29},{23,59,0}}\n\n\u003e uef_time:add_weeks({{2019, 1, 1}, {0, 1, 0}}, -4).\n{{2018,12,4},{0,1,0}}\n----\n\n'''\n\n==== uef_time:add_months/1\n\n[source,erlang]\n----\nuef_time:add_months(Months) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_months(erlang:localtime(), Months)`. See docs of link:#uef_timeadd_months2[uef_time:add_months/2].\n\n**Types:**\n\n[source,erlang]\n----\nMonths :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_months/2\n\n[source,erlang]\n----\nuef_time:add_months(DateOrDatetime, Months) -\u003e NewDateOrDateTime.\n----\n\nAdds the number of months `Months` to `DateOrDatetime` and returns a new *date or datetime* value. The type of `NewDateOrDateTime` is the same as the type of `DateOrDatetime`.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nMonths :: integer().\nNewDateOrDateTime :: calendar:date() | calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_months({2019, 1, 31}, 1).\n{2019,2,28}\n\n\u003e uef_time:add_months({2016, 1, 31}, 1).\n{2016,2,29}\n\n\u003e uef_time:add_months({2019, 1, 31}, -1).\n{2018,12,31}\n\n\u003e uef_time:add_months({{2019, 1, 1}, {23, 59, 0}}, 1).\n{{2019,2,1},{23,59,0}}\n\n\u003e uef_time:add_months({{2019, 1, 1}, {0, 1, 0}}, -1).\n{{2018,12,1},{0,1,0}}\n----\n\n'''\n\n==== uef_time:add_years/1\n\n[source,erlang]\n----\nuef_time:add_years(Years) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_years(erlang:localtime(), Years)`. See docs of link:#uef_timeadd_years2[uef_time:add_years/2].\n\n**Types:**\n\n[source,erlang]\n----\nYears :: integer().\nNewDateTime :: calendar:datetime().\n----\n\n'''\n\n==== uef_time:add_years/2\n\n[source,erlang]\n----\nuef_time:add_years(DateOrDatetime, Years) -\u003e NewDateOrDateTime.\n----\n\nAdds the number of years `Years` to `DateOrDatetime` and returns a new *date or datetime* value. The type of `NewDateOrDateTime` is the same as the type of `DateOrDatetime`.\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nYears :: integer().\nNewDateOrDateTime :: calendar:date() | calendar:datetime().\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_years({2019, 1, 31}, 1).\n{2020,1,31}\n\n\u003e uef_time:add_years({2019, 1, 31}, -1).\n{2018,1,31}\n\n\u003e uef_time:add_years({{2019, 1, 1}, {23, 59, 0}}, 1).\n{{2020,1,1},{23,59,0}}\n\n\u003e uef_time:add_years({{2019, 1, 1}, {0, 1, 0}}, -1).\n{{2018,1,1},{0,1,0}}\n----\n\n'''\n\n==== uef_time:add_time/1\n\n[source,erlang]\n----\nuef_time:add_time(Periods) -\u003e NewDateTime.\n----\n\nSame as `uef_time:add_time(erlang:localtime(), Periods)`. See docs of link:#uef_timeadd_time2[uef_time:add_time/2]. `NewDateTime` is of type `calendar:datetime()`. See types for `Periods` in *Types* section of function `uef_time:add_time/2`.\n\n'''\n\n==== uef_time:add_time/2\n\n[source,erlang]\n----\nuef_time:add_time(DateOrDatetime, Periods) -\u003e NewDateOrDateTime.\n----\n\nAdds one or more periods of time to `DateOrDatetime` and returns a new *date or datetime* value. This is a universal function based on functions `uef_time:add_seconds/2`, `uef_time:add_minutes/2`, `uef_time:add_hours/2`, `uef_time:add_days/2`, `uef_time:add_weeks/2`, `uef_time:add_months/2` and `uef_time:add_years/2`. The type of `NewDateOrDateTime` depends on the type of `DateOrDatetime` and `Periods` (see *Examples*).\n\n**Types:**\n\n[source,erlang]\n----\nDateOrDatetime :: calendar:date() | calendar:datetime().\nNewDateOrDateTime :: calendar:date() | calendar:datetime().\n\npsecond() :: sec | second | seconds.\npminute() :: min | minute | minutes.\nphour() :: hrs | hour | hours.\npday() :: day | days.\npmonth() :: month | months.\npyear() :: year | years.\nptype() :: psecond() | pminute() | phour() | pday() | pmonth() | pyear().\n\nperiod() :: {integer(), ptype()} | {ptype(), integer()}.\nperiods() :: [period()].\n----\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:add_time({2000, 1, 1}, [{1, year}, {1, month}, {1, week}, {1, day}, {1, hour}, {1, minute}, {1, second}]).\n{{2001,2,9},{1,1,1}}   % type calendar:datetime()\n\n\u003e uef_time:add_time({2000, 1, 1}, [{1, year}, {1, month}, {1, week}, {1, day}]).\n{2001,2,9}   % type calendar:date()\n\n\u003e uef_time:add_time({{2000, 1, 1}, {0, 0, 0}}, [{1, year}, {1, month}, {1, week}, {1, day}]).\n{{2001,2,9},{0,0,0}}   % type calendar:datetime()\n\n\u003e uef_time:add_time({2000, 1, 1}, [{year, 1}, {month, 1}, {week, 1}, {day, 1}, {hour, 1}, {minute, 1}, {second, 1}]).\n{{2001,2,9},{1,1,1}}\n\n\u003e uef_time:add_time({2000, 1, 1}, [{1, hrs}, {1, min}, {1, sec}]).\n{{2000,1,1},{1,1,1}}\n\n\u003e uef_time:add_time({{2000, 1, 31}, {23, 59, 59}}, [{1, hour}, {1, minute}, {1, second}]).\n{{2000,2,1},{1,1,0}}\n\n\u003e uef_time:add_time({{2000, 1, 31}, {23, 59, 59}}, [{1, second}]).\n{{2000,2,1},{0,0,0}}\n\n\u003e uef_time:add_time({2000, 1, 1}, [{1, years}]) =:= uef_time:add_years({2000, 1, 1}, 1).\ntrue\n\n\u003e uef_time:add_time({2000, 1, 1}, [{1, month}]) =:= uef_time:add_months({2000, 1, 1}, 1).\ntrue\n----\n\n'''\n\n==== uef_time:today/0\n\n[source,erlang]\n----\nuef_time:today() -\u003e CurrentDate.\n----\n\nReturns the current date as *{Year, Month, Day}*. Same as http://erlang.org/doc/man/erlang.html#date-0[erlang:date()]. `CurrentDate` is of type `calendar:date()`.\n\n'''\n\n==== uef_time:tomorrow/0\n\n[source,erlang]\n----\nuef_time:tomorrow() -\u003e TomorrowDate.\n----\n\nReturns tomorrow's date as *{Year, Month, Day}*. `TomorrowDate` is of type `calendar:date()`.\n\n'''\n\n==== uef_time:yesterday/0\n\n[source,erlang]\n----\nuef_time:yesterday() -\u003e YesterdayDate.\n----\n\nReturns yesterday's date as *{Year, Month, Day}*. `YesterdayDate` is of type `calendar:date()`.\n\n'''\n\n==== uef_time:unix_time/0\n\n[source,erlang]\n----\nuef_time:unix_time() -\u003e Seconds.\n----\n\nReturns the current number of seconds since 00:00:00 (UTC), 1 January 1970. It also known as *Unix time* or *POSIX time* or *UNIX Epoch time*.\n\n*Example:*\n\n[source,erlang]\n----\n\u003e uef_time:unix_time().\n1557670215\n----\n\n'''\n\n==== uef_time:unix_time/1\n\n[source,erlang]\n----\nuef_time:unix_time(Datetime) -\u003e Seconds.\n----\n\nReturns the number of seconds elapsed between *00:00:00 (UTC), 1 January 1970* and `Datetime`. `Datetime` must be of type `calenadr:datetime()`.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:unix_time({{1970,1,1}, {0,0,0}}).\n0\n\n\u003e uef_time:unix_time({{2000,1,1}, {23,59,59}}).\n946771199\n----\n\n'''\n\n==== uef_time:days_diff/1\n\n[source,erlang]\n----\nuef_time:days_diff(Date) -\u003e Days.\n----\n\nReturns the difference ***in days*** between `Date` and the current local date provided by function http://erlang.org/doc/man/erlang.html#date-0[erlang:date()]. `Date` must be of type `calendar:date()` (`{Year, Month, Day}`). `Days` is a positive value if `Date` is after `erlang:date()` or a negative value otherwise.\n\n'''\n\n==== uef_time:days_diff/2\n\n[source,erlang]\n----\nuef_time:days_diff(Date1, Date2) -\u003e Days.\n----\n\nReturns the difference ***in days*** between `Date2` and `Date1`. `Date1` and `Date2` must be of type `calendar:date()` (`{Year, Month, Day}`). `Days` is a positive value if `Date2` is after `Date1` or a negative value otherwise.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:days_diff({1999, 1, 31}, {2019, 12, 31}).\n7639\n\n\u003e uef_time:days_diff({2019, 12, 31}, {1999, 1, 31}).\n-7639\n----\n\n'''\n\n==== uef_time:seconds_diff/1\n\n[source,erlang]\n----\nuef_time:seconds_diff(DateTime) -\u003e Seconds.\n----\n\nReturns the difference ***in seconds*** between `Date` and the current local time provided by function http://erlang.org/doc/man/erlang.html#localtime-0[erlang:localtime()]. `DateTime` must be of type `calendar:datetime()` (`{{Year, Month, Day}, {Hour, Minute, Second}}`). `Seconds` is a positive value if `DateTime` is after `erlang:localtime()` or a negative value otherwise.\n\n'''\n\n==== uef_time:seconds_diff/2\n\n[source,erlang]\n----\nuef_time:seconds_diff(DateTime1, DateTime2) -\u003e Seconds.\n----\n\nReturns the difference ***in seconds*** between `DateTime2` and `DateTime1`.  `DateTime1` and `DateTime2` must be of type `calendar:datetime()` (`{{Year, Month, Day}, {Hour, Minute, Second}}`). `Seconds` is a positive value if `DateTime2` is after `DateTime1` or a negative value otherwise.\n\n*Examples:*\n\n[source,erlang]\n----\n\u003e uef_time:seconds_diff({{1999, 1, 31}, {0, 0, 0}}, {{2019, 12, 31}, {0, 0, 0}}).\n660009600\n\n\u003e uef_time:seconds_diff({{2019, 12, 31}, {0, 0, 0}}, {{1999, 1, 31}, {0, 0, 0}}).\n-660009600\n----\n\n'''\n\n== Build\n\n=== Build with GNU `make`\n\n[source,bash]\n----\nmake\n----\n\n=== Build with `rebar3`\n\n[source,bash]\n----\nrebar3 compile\n----\n\n== Test and dialyze\n\n=== Test/dialyze with GNU `make`\n\n[source,bash]\n----\nmake test\n----\n\n[source,bash]\n----\nmake dialyzer\n----\n\n[source,bash]\n----\nmake xref\n----\n\n[source,bash]\n----\nmake cover\n----\n\n=== Test/dialyze with `rebar3`\n\n[source,bash]\n----\nrebar3 eunit\n----\n\n[source,bash]\n----\nrebar3 dialyzer\n----\n\n[source,bash]\n----\nrebar3 xref\n----\n\n[source,bash]\n----\nrebar3 do eunit, cover\n----\n\n== Build documentation\n\n=== Build docs with GNU `make`\n\n[source,bash]\n----\nmake docs\n----\n\n=== Build docs with `rebar3`\n\n[source,bash]\n----\nrebar3 edoc\n----\n\n== Contributing\n\nYou are welcome :)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDOBRO%2Fuef-lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDOBRO%2Fuef-lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDOBRO%2Fuef-lib/lists"}