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 
10 import std.datetime;
11 
12 import vibe.data.serialization;
13 import vibe.data.json;
14 
15 /**
16  * Article structure returned when getting articles from the Me endpoint.
17  */
18 struct ArticleMe {
19     @optional string type_of;
20     @optional int id;
21     @optional string title;
22     @optional string description;
23     @optional string cover_image;
24     @optional bool published;
25     @optional SysTime published_timestamp;
26     @optional string[] tag_list;
27     @optional string canonical_url;
28     @optional string body_markdown;
29     @optional string slug;
30 }
31 
32 /**
33  * Article Structure defining data for creating an article on the Create endpoint.
34  */
35 struct ArticleCreate {
36     string title;
37     @optional string body_markdown;
38     @optional bool published;
39     @optional string series;
40     @optional string main_image;
41     @optional string canonical_url;
42     @optional string description;
43     @optional string[] tags;
44     @optional int organization_id;
45 }
46 
47 /**
48  * Deserialize a Json Blob into an array of `ArticleMe`.
49  */
50 @safe
51 auto meArticles(const Json resData) {
52     return deserializeJson!(const(ArticleMe)[])(resData);
53 } unittest {
54     auto exampleResponse = `[
55   {
56     "published_at":null,
57     "canonical_url":"http://example.com/",
58     "comments_count":0,
59     "page_views_count":0,
60     "id":12345,
61     "published":false,
62     "body_markdown":"Content Body",
63     "title":"Article Title",
64     "description":"",
65     "tag_list":[
66       "testing"
67     ],
68     "type_of":"article"
69   }]`.parseJsonString;
70 
71     ArticleMe ans;
72     ans.type_of = "article";
73     ans.id = 12345;
74     ans.title = "Article Title";
75     ans.description = "";
76     ans.cover_image = "";
77     ans.published = false;
78     ans.tag_list = ["testing"];
79     ans.canonical_url = "http://example.com/";
80     ans.body_markdown = "Content Body";
81 
82     import std.algorithm;
83     import std.conv;
84 
85     assert(meArticles(exampleResponse).equal([ans]), meArticles(exampleResponse).to!string);
86 }