1 /**
2  * This module provides had written structures for https://docs.dev.to/api/ and additional
3  * parsing methods.
4  *
5  * The structures may not reflect the complete data returned by the API as this will help
6  * on the items important to this application.
7  */
8 module devto.api;
9 import vibe.data.serialization;
10 import vibe.data.json;
11 
12 /**
13  * Article structure returned when getting articles from the Me endpoint.
14  */
15 struct ArticleMe {
16     @optional string type_of;
17     @optional int id;
18     @optional string title;
19     @optional string description;
20     @optional string cover_image;
21     @optional bool published;
22     @optional string[] tag_list;
23     @optional string canonical_url;
24     @optional string body_markdown;
25     @optional string slug;
26 }
27 
28 /**
29  * Article Structure defining data for creating an article on the Create endpoint.
30  */
31 struct ArticleCreate {
32     string title;
33     @optional string body_markdown;
34     @optional bool published;
35     @optional string series;
36     @optional string main_image;
37     @optional string canonical_url;
38     @optional string description;
39     @optional string[] tags;
40     @optional int organization_id;
41 }
42 
43 /**
44  * Deserialize a Json Blob into an array of `ArticleMe`.
45  */
46 @safe
47 auto meArticles(const Json resData) {
48     return deserializeJson!(const(ArticleMe)[])(resData);
49 } unittest {
50     auto exampleResponse = `[
51   {
52     "published_at":null,
53     "canonical_url":"http://example.com/",
54     "comments_count":0,
55     "page_views_count":0,
56     "id":12345,
57     "published":false,
58     "body_markdown":"Content Body",
59     "title":"Article Title",
60     "description":"",
61     "tag_list":[
62       "testing"
63     ],
64     "type_of":"article"
65   }]`.parseJsonString;
66 
67     ArticleMe ans;
68     ans.type_of = "article";
69     ans.id = 12345;
70     ans.title = "Article Title";
71     ans.description = "";
72     ans.cover_image = "";
73     ans.published = false;
74     ans.tag_list = ["testing"];
75     ans.canonical_url = "http://example.com/";
76     ans.body_markdown = "Content Body";
77 
78     import std.algorithm;
79     import std.conv;
80 
81     assert(meArticles(exampleResponse).equal([ans]), meArticles(exampleResponse).to!string);
82 }