diff --git a/ebin/erlware_commons.app b/ebin/erlware_commons.app new file mode 100644 index 0000000..9e27845 --- /dev/null +++ b/ebin/erlware_commons.app @@ -0,0 +1,7 @@ +%% -*- mode: Erlang; fill-column: 75; comment-column: 50; -*- +{application, erlware_commons, + [{description, "Additional standard library for Erlang"}, + {vsn, "0.0.1"}, + {modules, [ec_lists]}, + {registered, []}, + {applications, [kernel, stdlib]}]}. diff --git a/src/ec_lists.erl b/src/ec_lists.erl new file mode 100644 index 0000000..816a584 --- /dev/null +++ b/src/ec_lists.erl @@ -0,0 +1,178 @@ +%%%------------------------------------------------------------------- +%%% @copyright (C) 2011, Erlware LLC +%%% @doc +%%% Provides useful functionionality on standard lists that are +%%% not provided in the standard library. +%%% @end +%%%------------------------------------------------------------------- +-module(ec_lists). + +%% API +-export([find/2, + fetch/2]). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%% @doc Find a value in the list with the specified function. If the +%% function returns the atom true, the value is returned as {ok, +%% term()} and processing is aborted, if the function returns false, +%% processing continues until the end of the list. If the end is found +%% and the function never returns true the atom error is returned. +-spec find([term()], fun()) -> {ok, term()} | error. +find([Head | Tail], Fun) + when is_function(Fun) -> + case Fun(Head) of + true -> + {ok, Head}; + false -> + find(Tail, Fun) + end; +find([], _Fun) -> + error. + +%% @doc Fetch a value from the list. If the function returns true the +%% value is returend. If processing reaches the end of the list and +%% the function has never returned true an exception not_found is +%% thrown. +-spec fetch(list(), fun()) -> term(). +fetch(List, Fun) + when is_list(List), + is_function(Fun) -> + case find(List, Fun) of + {ok, Head} -> + Head; + error -> + throw(not_found) + end. + +%%%=================================================================== +%%% API +%%%=================================================================== + +-ifndef(NOTEST). +-include_lib("eunit/include/eunit.hrl"). + +find1_test() -> + TestData = [1, 2, 3, 4, 5, 6], + Result = find(TestData, + fun(5) -> + true; + (_) -> + false + end), + ?assertMatch({ok, 5}, Result), + + Result2 = find(TestData, + fun(37) -> + true; + (_) -> + false + end), + ?assertMatch(error, Result2). + +find2_test() -> + TestData = ["one", "two", "three", "four", "five", "six"], + Result = find(TestData, + fun("five") -> + true; + (_) -> + false + end), + ?assertMatch({ok, "five"}, Result), + + Result2 = find(TestData, + fun(super_duper) -> + true; + (_) -> + false + end), + ?assertMatch(error, Result2). + + + +find3_test() -> + TestData = [{"one", 1}, {"two", 2}, {"three", 3}, {"four", 5}, {"five", 5}, + {"six", 6}], + Result = find(TestData, + fun({"one", 1}) -> + true; + (_) -> + false + end), + ?assertMatch({ok, {"one", 1}}, Result), + + Result2 = find(TestData, + fun([fo, bar, baz]) -> + true; + ({"onehundred", 100}) -> + true; + (_) -> + false + end), + ?assertMatch(error, Result2). + + + +fetch1_test() -> + TestData = [1, 2, 3, 4, 5, 6], + Result = fetch(TestData, + fun(5) -> + true; + (_) -> + false + end), + ?assertMatch(5, Result), + + ?assertThrow(not_found, + fetch(TestData, + fun(37) -> + true; + (_) -> + false + end)). + +fetch2_test() -> + TestData = ["one", "two", "three", "four", "five", "six"], + Result = fetch(TestData, + fun("five") -> + true; + (_) -> + false + end), + ?assertMatch("five", Result), + + ?assertThrow(not_found, + fetch(TestData, + fun(super_duper) -> + true; + (_) -> + false + end)). + +fetch3_test() -> + TestData = [{"one", 1}, {"two", 2}, {"three", 3}, {"four", 5}, {"five", 5}, + {"six", 6}], + Result = fetch(TestData, + fun({"one", 1}) -> + true; + (_) -> + false + end), + ?assertMatch({"one", 1}, Result), + + ?assertThrow(not_found, + fetch(TestData, + fun([fo, bar, baz]) -> + true; + ({"onehundred", 100}) -> + true; + (_) -> + false + end)). + + + + +-endif.