1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/*
*
* Copyright (C) 2026 Andromeda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
module radapi;
import std::io;
import std::core::string;
import curl;
enum Request : int (String path, int args)
{
DELEGATES_REPOS { "/delegates/$1/repos", 1 },
NODE { "/node", 0 },
NODE_POLICIES_REPOS { "/node/policies/repos", 0 },
NODE_POLICIES_REPO { "/node/policies/repos/$1", 1 },
NODES { "/nodes/$1", 1 },
NODES_INVENTORY { "/nodes/$1/inventory", 1 },
REPO_ROOT { "/repos", 0 },
REPO_SEARCH { "/repos/search", 0 },
REPO { "/repos/$1", 1 },
HISTORY { "/repos/$1/commits", 1 },
COMMIT { "/repos/$1/commits/$2", 2 },
DIFF { "/repos/$1/diff/$2/$3", 3 },
ACTIVITY { "/repos/$1/activity", 1 },
TREE_ROOT { "/repos/$1/tree/$2/", 2 },
TREE { "/repos/$1/tree/$2/$3", 3 },
STATS_TREE { "/repos/$1/stats/tree/$2", 2 },
REMOTES { "/repos/$1/remotes", 1 },
REMOTE { "/repos/$1/remotes/$2", 2 },
BLOB { "/repos/$1/blob/$2/$3", 3 },
README { "/repos/$1/readme/$2", 2 },
JOB { "/repos/$1/jobs/$2", 2 },
ISSUES { "/repos/$1/issues", 1 },
ISSUE { "/repos/$1/issues/$2", 2 },
PATCHES { "/repos/$1/patches", 1 },
PATCH { "/repos/$1/patches/$2", 2 },
STATS { "/stats", 0 },
}
struct Client
{
Curl* c;
char[10485760]* buffer;
String endpoint;
usz buffer_index;
}
fn Client* new_client(String endpoint)
{
Client* self = mem::alloc(Client);
self.c = curl::easy_init();
self.endpoint = endpoint;
self.buffer = mem::alloc(char[10485760]);
curl::easy_setopt(self.c, CurlOption.WRITEFUNCTION, &cb);
curl::easy_setopt(self.c, CurlOption.WRITEDATA, self);
return self;
}
fn CurlResult Client.request(Client* self, Request r, String params, String... args)
{
self.buffer_index = 0;
CurlResult cr;
String s;
@pool()
{
s = self.endpoint.tconcat(r.path);
int i;
while (i < r.args)
{
s = s.treplace(string::tformat("$%d", i+1), args[i]);
i++;
}
s = s.tconcat(params);
curl::easy_setopt(self.c, CurlOption.URL, s);
cr = curl::easy_perform(self.c);
};
return cr;
}
fn String Client.response(Client* self)
{
return (String)self.buffer.[..self.buffer_index];
}
fn usz cb(char* buffer, usz size, usz nitems, Client* client)
{
client.buffer.[client.buffer_index..client.buffer_index+nitems-1] = buffer[..nitems-1];
client.buffer_index += nitems;
return nitems;
}
|