diff options
author | Louis Pilfold <louis@lpil.uk> | 2020-05-19 18:55:06 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2020-05-19 19:22:49 +0100 |
commit | 5ca885bd114635244d25f2f91c35bda448e6a635 (patch) | |
tree | 3139a84b322575e8044e392d2df6d88ba95840f3 /src | |
parent | cbf07061be7524aa049864b6dec49715e641499a (diff) | |
download | gleam_stdlib-5ca885bd114635244d25f2f91c35bda448e6a635.tar.gz gleam_stdlib-5ca885bd114635244d25f2f91c35bda448e6a635.zip |
list.filter_map
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/gleam_uri_native.erl | 20 | ||||
-rw-r--r-- | src/gleam/list.gleam | 32 | ||||
-rw-r--r-- | src/gleam/uri.gleam | 36 |
3 files changed, 67 insertions, 21 deletions
diff --git a/src/gleam/gleam_uri_native.erl b/src/gleam/gleam_uri_native.erl index 5d225cb..dafd406 100644 --- a/src/gleam/gleam_uri_native.erl +++ b/src/gleam/gleam_uri_native.erl @@ -1,5 +1,5 @@ -module (gleam_uri_native). --export ([parse/1, to_string/1, parse_query/1]). +-export ([parse/1]). find_key(Key, Map) -> case maps:find(Key, Map) of @@ -25,21 +25,3 @@ parse(String) -> find_key(fragment, Map) }} end. - -to_string({uri, MaybeScheme, MaybeUserinfo, MaybeHost, MaybePort, Path, MaybeQuery, MaybeFragment}) -> - Components = [{scheme, MaybeScheme}, {userinfo, MaybeUserinfo}, {host, MaybeHost}, {port, MaybePort}, {path, {ok, Path}}, {query, MaybeQuery}, {fragment, MaybeFragment}], - Map = maps:from_list([{K, V} || {K, {ok, V}} <- Components]), - case uri_string:recompose(Map) of - String when is_binary(String) -> - String; - % Return value when empty - [] -> <<"">> - end. - -parse_query(String) -> - case uri_string:dissect_query(String) of - {error, _Reason, _Term} -> - {error, nil}; - Parts -> - {ok, Parts} - end. diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index a0098a1..4e10c15 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -196,6 +196,38 @@ pub fn filter(list: List(a), for predicate: fn(a) -> Bool) -> List(a) { do_filter(list, predicate, []) } +fn do_filter_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + Ok(x) -> [x, ..acc] + Error(_) -> acc + } + do_filter_map(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `True`. +/// +/// ## Examples +/// +/// > filter_map([2, 4, 6, 1], Error) +/// [] +/// +/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) +/// [3, 4, 6, 2] +/// +pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { + do_filter_map(list, fun, []) +} + fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { case list { [] -> reverse(acc) diff --git a/src/gleam/uri.gleam b/src/gleam/uri.gleam index 8536d98..a62cf3c 100644 --- a/src/gleam/uri.gleam +++ b/src/gleam/uri.gleam @@ -11,6 +11,7 @@ import gleam/list import gleam/result.{Option} import gleam/string import gleam/dynamic.{Dynamic} +import gleam/map.{Map} /// Type representing holding the parsed components of an URI. /// All components of a URI are optional, except the path. @@ -100,9 +101,40 @@ pub fn path_segments(path) { do_path_segments(string.split(path, "/"), []) } +type UriKey { + Scheme + Userinfo + Host + Port + Path + Query + Fragment +} + +external fn erl_to_string(Map(UriKey, Dynamic)) -> Dynamic = + "uri_string" "recompose" + /// Encode a `Uri` value as a URI string. /// /// The opposite operation is `uri.parse`. /// -pub external fn to_string(Uri) -> String = - "gleam_uri_native" "to_string" +pub fn to_string(uri: Uri) -> String { + let field = fn(key: UriKey, value: Option(anything)) { + result.map(value, fn(value) { tuple(key, dynamic.from(value)) }) + } + + [ + field(Scheme, uri.scheme), + field(Userinfo, uri.userinfo), + field(Host, uri.host), + field(Port, uri.port), + field(Path, Ok(uri.path)), + field(Query, uri.query), + field(Fragment, uri.fragment), + ] + |> list.filter_map(fn(x) { x }) + |> map.from_list + |> erl_to_string + |> dynamic.string + |> result.unwrap("") +} |