summaryrefslogtreecommitdiff
path: root/radapi.c3
blob: f8c35eb01ef684265a178a0798db86dbaa741e85 (plain)
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;
}