Use optional package

This commit is contained in:
Johannes Loher 2019-06-05 01:38:26 +02:00
parent f9f4bbf19f
commit 940aae65e5
8 changed files with 49 additions and 28 deletions

View file

@ -4,8 +4,9 @@ authors "Johannes Loher"
copyright "Copyright © 2018, Johannes Loher" copyright "Copyright © 2018, Johannes Loher"
license "MIT" license "MIT"
dependency "aedi" version="~>1.0.0" dependency "aedi" version="~>1.0.0"
dependency "fluent-asserts" version="~>0.12.3" dependency "fluent-asserts" version="~>0.12.4"
dependency "vibe-d" version="~>0.8.4" dependency "vibe-d" version="~>0.8.5"
dependency "optional" version="~>0.15.0"
configuration "executable" { configuration "executable" {
targetType "executable" targetType "executable"

View file

@ -2,21 +2,24 @@
"fileVersion": 1, "fileVersion": 1,
"versions": { "versions": {
"aedi": "1.0.0", "aedi": "1.0.0",
"bolts": "0.11.1",
"botan": "1.12.10", "botan": "1.12.10",
"botan-math": "1.0.3", "botan-math": "1.0.3",
"ddmp": "0.0.1-0.dev.3", "ddmp": "0.0.1-0.dev.3",
"diet-ng": "1.5.0", "diet-ng": "1.5.0",
"eventcore": "0.8.40", "eventcore": "0.8.43",
"fluent-asserts": "0.12.3", "fluent-asserts": "0.12.4",
"libasync": "0.8.3", "libasync": "0.8.4",
"libdparse": "0.8.8", "libdparse": "0.8.8",
"libevent": "2.0.2+2.0.16", "libevent": "2.0.2+2.0.16",
"memutils": "0.4.13", "memutils": "0.4.13",
"mir-linux-kernel": "1.0.1", "mir-linux-kernel": "1.0.1",
"openssl": "1.1.6+1.0.1g", "openssl": "1.1.6+1.0.1g",
"optional": "0.15.0",
"silly": "0.8.2",
"stdx-allocator": "2.77.5", "stdx-allocator": "2.77.5",
"taggedalgebraic": "0.10.12", "taggedalgebraic": "0.11.4",
"vibe-core": "1.4.6", "vibe-core": "1.6.2",
"vibe-d": "0.8.4" "vibe-d": "0.8.5"
} }
} }

View file

@ -36,10 +36,13 @@ public:
{ {
import std.exception : enforce; import std.exception : enforce;
import vibe.http.common : HTTPStatus, HTTPStatusException; import vibe.http.common : HTTPStatus, HTTPStatusException;
import optional.optional : orElse;
immutable maybeTodo = todoRepository.findByUuid(uuid); immutable todo = todoRepository.findByUuid(uuid).orElse!(function Todo() {
enforce(!maybeTodo.isNull, new HTTPStatusException(HTTPStatus.NotFound)); throw new HTTPStatusException(HTTPStatus.NotFound);
return maybeTodo.get; });
return todo;
} }
Todo updateTodo(UUID uuid, const TodoUpdateDO todoUpdate) @safe Todo updateTodo(UUID uuid, const TodoUpdateDO todoUpdate) @safe
@ -66,10 +69,10 @@ public:
interface TodoRepository interface TodoRepository
{ {
import std.typecons : Nullable; import optional.optional : Optional;
Todo save(Todo todo) @safe; Todo save(Todo todo) @safe;
bool remove(Todo todo) @safe; bool remove(Todo todo) @safe;
Nullable!Todo findByUuid(UUID uuid) @safe; Optional!Todo findByUuid(UUID uuid) @safe;
Todo[] findAll() @safe; Todo[] findAll() @safe;
} }

View file

@ -5,22 +5,22 @@ import std.typecons : Nullable;
import std.uuid : UUID; import std.uuid : UUID;
import vibe.web.rest : path; import vibe.web.rest : path;
@path("/api/v1/todos") @path("/api/v1/")
interface TodoApi interface TodoApi
{ {
@path("/") @path("todos")
TodoTO addTodo(string title, string content) @safe; TodoTO addTodo(string title, string content) @safe;
@path("/") @path("todos")
TodoTO[] getTodos() @safe; TodoTO[] getTodos() @safe;
@path("/:uuid") @path("todos/:uuid")
TodoTO getTodo(UUID _uuid) @safe; TodoTO getTodo(UUID _uuid) @safe;
@path("/:uuid") @path("todos/:uuid")
TodoTO updateTodo(UUID _uuid, Nullable!string title, Nullable!string content) @safe; TodoTO updateTodo(UUID _uuid, Nullable!string title, Nullable!string content) @safe;
@path("/:uuid") @path("todos/:uuid")
void deleteTodo(UUID _uuid) @safe; void deleteTodo(UUID _uuid) @safe;
} }

View file

@ -10,7 +10,7 @@ version (unittest)
class InMemoryTodoRepository : TodoRepository class InMemoryTodoRepository : TodoRepository
{ {
import d_webservice_example.model.todo : Todo; import d_webservice_example.model.todo : Todo;
import std.typecons : Nullable, nullable; import optional.optional : Optional;
import std.uuid : randomUUID, UUID; import std.uuid : randomUUID, UUID;
private: private:
@ -71,15 +71,11 @@ public:
return todos.byValue.array; return todos.byValue.array;
} }
override Nullable!Todo findByUuid(UUID uuid) override Optional!Todo findByUuid(UUID uuid)
{ {
import std.algorithm.searching : find; import d_webservice_example.util.algorithm : findFirst;
auto foundTodos = todos.byValue.find!(todo => todo.uuid == uuid); return todos.byValue.findFirst!(todo => todo.uuid == uuid);
if (foundTodos.empty)
return Nullable!Todo.init;
else
return nullable(foundTodos.front);
} }
override bool remove(Todo todo) override bool remove(Todo todo)

View file

@ -2,7 +2,6 @@ module d_webservice_example.transport.todo_to;
struct TodoTO struct TodoTO
{ {
import std.typecons : Nullable;
import std.uuid : UUID; import std.uuid : UUID;
UUID uuid; UUID uuid;

View file

@ -0,0 +1,13 @@
module d_webservice_example.util.algorithm;
import d_webservice_example.util.meta : from;
auto findFirst(alias pred, InputRange)(InputRange haystack)
if (from!"std.range".isInputRange!InputRange)
{
import optional.optional : toOptional;
import std.algorithm.searching : find;
import std.range : take;
return haystack.find!(pred).take(1).toOptional();
}

View file

@ -0,0 +1,6 @@
module d_webservice_example.util.meta;
template from(string moduleName)
{
mixin("import from = " ~ moduleName ~ ";");
}