Skip to content

Commit a07a162

Browse files
Fix PR issues: enum defaults, CMake FetchContent, Exception init, and model base class generation
1 parent 13e163e commit a07a162

File tree

5 files changed

+71
-12
lines changed

5 files changed

+71
-12
lines changed

src/SDK/Language/Cpp.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ public function getFiles(): array
159159
'destination' => 'include/appwrite/services/{{ service.name | caseSnake }}.hpp',
160160
'template' => 'cpp/include/services/service.hpp.twig',
161161
],
162+
[
163+
'scope' => 'default',
164+
'destination' => 'include/appwrite/model.hpp',
165+
'template' => 'cpp/include/model.hpp.twig',
166+
],
162167
[
163168
'scope' => 'definition',
164169
'destination' => 'include/appwrite/models/{{ definition.name | caseSnake }}.hpp',
@@ -257,6 +262,53 @@ public function getParamDefault(array $param): string
257262

258263
$output = ' = ';
259264

265+
if (isset($param['enumValues']) && !empty($param['enumValues'])) {
266+
$enumValues = $param['enumValues'];
267+
$enumKeys = $param['enumKeys'] ?? [];
268+
$enumName = $this->toPascalCase($param['enumName'] ?? $param['name'] ?? '');
269+
270+
$resolveKey = function ($value) use ($enumValues, $enumKeys) {
271+
$index = array_search($value, $enumValues, true);
272+
if ($index !== false && isset($enumKeys[$index]) && $enumKeys[$index] !== '') {
273+
$cleaned = \preg_replace('/[^a-zA-Z0-9]/', '', $enumKeys[$index]);
274+
return $this->toUpperSnakeCase($cleaned);
275+
}
276+
if ($index !== false && isset($enumValues[$index])) {
277+
$cleaned = \preg_replace('/[^a-zA-Z0-9]/', '', $enumValues[$index]);
278+
return $this->toUpperSnakeCase($cleaned);
279+
}
280+
$fallback = $enumKeys[0] ?? $enumValues[0] ?? $value;
281+
$cleaned = \preg_replace('/[^a-zA-Z0-9]/', '', (string)$fallback);
282+
return $this->toUpperSnakeCase($cleaned);
283+
};
284+
285+
if ($type === self::TYPE_ARRAY) {
286+
$values = [];
287+
if (\is_string($default) && $default !== '') {
288+
$decoded = json_decode($default, true);
289+
if (\is_array($decoded)) {
290+
$values = $decoded;
291+
}
292+
} elseif (\is_array($default)) {
293+
$values = $default;
294+
}
295+
296+
if (empty($values)) {
297+
// return empty vector for array array initialization without default
298+
return $output . '{}';
299+
}
300+
301+
$items = array_map(function ($value) use ($enumName, $resolveKey) {
302+
return 'appwrite::enums::' . $enumName . '::' . $resolveKey($value);
303+
}, $values);
304+
305+
return $output . '{ ' . implode(', ', $items) . ' }';
306+
}
307+
308+
$value = ($default !== null && $default !== '') ? $default : $enumValues[0];
309+
return $output . 'appwrite::enums::' . $enumName . '::' . $resolveKey($value);
310+
}
311+
260312
if (empty($default) && $default !== 0 && $default !== false) {
261313
switch ($type) {
262314
case self::TYPE_NUMBER:

templates/cpp/README.md.twig

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@
99
Add the following to your `CMakeLists.txt`:
1010

1111
```cmake
12-
find_package({{ sdk.name | caseSnake }} REQUIRED)
12+
include(FetchContent)
13+
FetchContent_Declare(
14+
{{ sdk.name | caseSnake }}
15+
GIT_REPOSITORY https://github.com/appwrite/sdk-for-cpp.git
16+
GIT_TAG main
17+
)
18+
FetchContent_MakeAvailable({{ sdk.name | caseSnake }})
19+
1320
target_link_libraries(my_app PRIVATE {{ sdk.name | caseSnake }})
1421
```
1522

templates/cpp/include/client.hpp.twig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public:
127127
try {
128128
return nlohmann::json::parse(response.text).get<T>();
129129
} catch (const nlohmann::json::parse_error& e) {
130-
throw Exception("Failed to parse response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, "parse_error", response.text);
130+
throw Exception("Failed to parse response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, response.text, "parse_error");
131131
}
132132
}
133133

@@ -340,7 +340,7 @@ private:
340340
if (method == "PATCH") return session.Patch();
341341
if (method == "DELETE") return session.Delete();
342342

343-
throw Exception("Appwrite SDK: Unsupported HTTP method: " + std::string(method), 0, "unsupported_method");
343+
throw Exception("Appwrite SDK: Unsupported HTTP method: " + std::string(method), 0, "", "unsupported_method");
344344
}
345345

346346
/**
@@ -369,7 +369,7 @@ private:
369369
try {
370370
return nlohmann::json::parse(response.text).get<T>();
371371
} catch (const nlohmann::json::parse_error& e) {
372-
throw Exception("Failed to parse response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, "parse_error", response.text);
372+
throw Exception("Failed to parse response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, response.text, "parse_error");
373373
}
374374
}
375375

@@ -433,7 +433,7 @@ private:
433433
try {
434434
lastResponse = nlohmann::json::parse(response.text);
435435
} catch (const nlohmann::json::parse_error& e) {
436-
throw Exception("Failed to parse chunk response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, "chunk_parse_error", response.text);
436+
throw Exception("Failed to parse chunk response JSON: " + std::string(e.what()) + ". Original response: " + response.text, response.status_code, response.text, "chunk_parse_error");
437437
}
438438

439439
if (uploadId.empty() && lastResponse.contains("$id")) {
@@ -448,7 +448,7 @@ private:
448448
}
449449

450450
if (lastResponse.is_null()) {
451-
throw Exception("Chunked upload failed to initialize or complete.", 0, "upload_failure");
451+
throw Exception("Chunked upload failed to initialize or complete.", 0, "", "upload_failure");
452452
}
453453

454454
return lastResponse.get<T>();
@@ -466,9 +466,9 @@ private:
466466
std::string contentType = (it != response.header.end()) ? it->second : "";
467467

468468
if (contentType.find("application/json") != std::string::npos) {
469-
throw Exception("", response.status_code, "", response.text);
469+
throw Exception("", response.status_code, response.text, "");
470470
} else {
471-
throw Exception("Server Error (" + std::to_string(response.status_code) + "): Non-JSON response received.", response.status_code, "server_error", response.text);
471+
throw Exception("Server Error (" + std::to_string(response.status_code) + "): Non-JSON response received.", response.status_code, response.text, "server_error");
472472
}
473473
}
474474
}

templates/cpp/include/exception.hpp.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public:
1111
Exception(const std::string& message, int code = 0, const std::string& response = "", const std::string& type = "")
1212
: message_(message), code_(code), response_(response), type_(type) {
1313

14-
if (type_.empty() || message_ == response_) {
14+
if (type_.empty() || message_.empty()) {
1515
try {
1616
if (!response_.empty() && response_.front() == '{') {
1717
auto json = nlohmann::json::parse(response_);
18-
if (json.contains("message") && json["message"].is_string() && message_ == response_) {
18+
if (json.contains("message") && json["message"].is_string() && message_.empty()) {
1919
message_ = json["message"].get<std::string>();
2020
}
2121
if (json.contains("type") && json["type"].is_string() && type_.empty()) {

templates/cpp/include/services/service.hpp.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public:
5959
*/
6060
{{ method | returnType(spec, 'appwrite') }} {{ method.name | caseCamel | overrideIdentifier }}(
6161
{%- for parameter in method.parameters.all %}
62-
{{ parameter | propertyType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{% if not loop.last %}, {% endif %}
62+
{{ parameter | propertyType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{{ parameter | paramDefault | raw }}{% if not loop.last %}, {% endif %}
6363
{%- endfor %}
6464
) {
6565
std::string path = "{{ method.path }}";
@@ -137,7 +137,7 @@ public:
137137
*/
138138
std::future<{{ method | returnType(spec, 'appwrite') }}> {{ method.name | caseCamel | overrideIdentifier }}Async(
139139
{%- for parameter in method.parameters.all %}
140-
{{ parameter | propertyType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{% if not loop.last %}, {% endif %}
140+
{{ parameter | propertyType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{{ parameter | paramDefault | raw }}{% if not loop.last %}, {% endif %}
141141
{%- endfor %}
142142
) {
143143
return std::async(std::launch::async, [=, this]() -> {{ method | returnType(spec, 'appwrite') }} {

0 commit comments

Comments
 (0)