-
-
Save sm9cc/0eaacc508205ff22c78b13b5dcf80553 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GNU Lesser General Public License | |
* Version 3, 29 June 2007 | |
* | |
* Copyright (C) 2023 Michael Bolden Jnr | |
* | |
* Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not | |
* allowed. | |
* | |
* This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU | |
* General Public License. | |
* | |
* --------------------------------------------------------------------------------------------------------------------- | |
* | |
* This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General | |
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any | |
* later version. | |
* | |
* This software 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 Lesser General Public License for more | |
* details. | |
* | |
* You should have received a copy of the GNU Lesser General Public License along with this program. If not, see | |
* <http://www.gnu.org/licenses/>. | |
* | |
*/ | |
#include "libSM9/Json.hpp" | |
#include "libSM9/Time.hpp" | |
#include <iostream> | |
namespace SM9 { | |
int JsonValue::getAnInt(const std::initializer_list<const char*>& keys, int fallback) const { | |
for (const auto& key : keys) { | |
if (value_.HasMember(key) && value_[key].IsInt()) { | |
return value_[key].GetInt(); | |
} | |
} | |
return fallback; | |
} | |
double JsonValue::getADouble(const std::initializer_list<const char*>& keys, double fallback) const { | |
for (const auto& key : keys) { | |
if (value_.HasMember(key) && value_[key].IsDouble()) { | |
return value_[key].GetDouble(); | |
} | |
} | |
return fallback; | |
} | |
std::chrono::system_clock::time_point JsonValue::getATimePoint( | |
const std::initializer_list<const char*>& keys, const std::chrono::system_clock::time_point& fallback) const { | |
for (const auto& key : keys) { | |
if (value_.HasMember(key)) { | |
// Issue: Detecting the correct JSON value type (int or string) for time can be unreliable. | |
// Workaround: Convert the value to an integer as a first attempt, then to a string if needed. | |
std::string value = std::to_string(value_[key].GetInt()); | |
if (value.empty()) { | |
value = value_[key].GetString(); | |
} | |
return Time::toPoint(value); | |
} | |
} | |
return fallback; | |
} | |
std::string JsonValue::getAString(const std::initializer_list<const char*>& keys, const std::string& fallback) const { | |
if (!value_.IsObject()) { | |
return fallback; | |
} | |
for (const auto& key : keys) { | |
if (value_.HasMember(key) && value_[key].IsString()) { | |
return value_[key].GetString(); | |
} | |
} | |
return fallback; | |
} | |
std::vector<std::string> JsonValue::getAnArrayOfStrings( | |
const std::initializer_list<const char*>& keys, const std::vector<std::string>& fallback) const { | |
for (const auto& key : keys) { | |
if (value_.HasMember(key) && value_[key].IsArray()) { | |
const auto& jsonArray = value_[key].GetArray(); | |
std::vector<std::string> result; | |
result.reserve(jsonArray.Size()); | |
for (const auto& value : jsonArray) { | |
if (value.IsString()) { | |
result.push_back(value.GetString()); | |
} | |
} | |
return result; | |
} | |
} | |
return fallback; | |
} | |
} // namespace SM9 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GNU Lesser General Public License | |
* Version 3, 29 June 2007 | |
* | |
* Copyright (C) 2023 Michael Bolden Jnr | |
* | |
* Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not | |
* allowed. | |
* | |
* This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU | |
* General Public License. | |
* | |
* --------------------------------------------------------------------------------------------------------------------- | |
* | |
* This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General | |
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any | |
* later version. | |
* | |
* This software 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 Lesser General Public License for more | |
* details. | |
* | |
* You should have received a copy of the GNU Lesser General Public License along with this program. If not, see | |
* <http://www.gnu.org/licenses/>. | |
* | |
*/ | |
#pragma once | |
#include "libSM9/Arch/Package.hpp" | |
#include <chrono> | |
#include <rapidjson/document.h> | |
#include <string> | |
#include <vector> | |
namespace SM9 { | |
class JsonValue { | |
public: | |
explicit JsonValue(const rapidjson::Value& value) : value_(value) { } | |
int getAnInt(const std::initializer_list<const char*>& keys, int fallback = 0) const; | |
double getADouble(const std::initializer_list<const char*>& keys, double fallback = 0.0) const; | |
std::string getAString(const std::initializer_list<const char*>& keys, const std::string& fallback = "") const; | |
std::vector<std::string> getAnArrayOfStrings( | |
const std::initializer_list<const char*>& keys, const std::vector<std::string>& fallback = {}) const; | |
std::chrono::system_clock::time_point getATimePoint(const std::initializer_list<const char*>& keys, | |
const std::chrono::system_clock::time_point& fallback = std::chrono::system_clock::time_point{}) const; | |
private: | |
const rapidjson::Value& value_; | |
}; | |
} // namespace SM9 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GNU Lesser General Public License | |
* Version 3, 29 June 2007 | |
* | |
* Copyright (C) 2023 Michael Bolden Jnr | |
* | |
* Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not | |
* allowed. | |
* | |
* This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU | |
* General Public License. | |
* | |
* --------------------------------------------------------------------------------------------------------------------- | |
* | |
* This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General | |
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any | |
* later version. | |
* | |
* This software 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 Lesser General Public License for more | |
* details. | |
* | |
* You should have received a copy of the GNU Lesser General Public License along with this program. If not, see | |
* <http://www.gnu.org/licenses/>. | |
*/ | |
#pragma once | |
#include "libSM9/Arch/Package.hpp" | |
#include "libSM9/Formatting/Formatting.hpp" | |
#include <cpr/api.h> | |
#include <cpr/response.h> | |
#include <glaze/core/common.hpp> | |
#include <glaze/json/read.hpp> | |
#include <optional> | |
#include <vector> | |
namespace glz { | |
template <class T> struct meta; | |
} | |
struct ResultMeta { | |
std::optional<SM9::Arch::Package> getPackage() const; | |
std::optional<std::string> base{}; | |
std::optional<std::string> name{}; | |
std::optional<std::string> version{}; | |
std::optional<std::string> release{}; | |
std::optional<long> epoch{}; | |
std::optional<std::string> description{}; | |
std::optional<std::string> architecture{}; | |
std::optional<std::string> url{}; | |
std::optional<std::vector<std::string>> licenses{}; | |
std::optional<std::vector<std::string>> groups{}; | |
std::optional<std::vector<std::string>> dependencies{}; | |
std::optional<std::vector<std::string>> makeDependencies{}; | |
std::optional<std::vector<std::string>> checkDependencies{}; | |
std::optional<std::vector<std::string>> optDependencies{}; | |
std::optional<std::vector<std::string>> provides{}; | |
std::optional<std::vector<std::string>> conflicts{}; | |
std::optional<std::vector<std::string>> replaces{}; | |
std::optional<std::string> repository{}; | |
std::optional<std::string> filename{}; | |
std::optional<int> compressedSize{}; | |
std::optional<int> installedSize{}; | |
std::optional<std::string> buildDate{}; | |
std::optional<std::variant<std::string, int>> lastUpdated{}; | |
std::optional<std::variant<std::string, int>> outOfDateSince{}; | |
std::optional<std::variant<std::string, std::vector<std::string>>> maintainers{}; | |
std::optional<std::string> packager{}; | |
std::optional<int> firstSubmitted{}; | |
std::optional<int> ID{}; | |
std::optional<std::vector<std::string>> keywords{}; | |
std::optional<int> voteCount{}; | |
std::optional<int> baseID{}; | |
std::optional<double> popularity{}; | |
std::optional<std::string> urlPath{}; | |
}; | |
struct QueryMeta { | |
int resultCount{0}; | |
bool hasResults{false}; | |
std::optional<std::vector<ResultMeta>> results{}; | |
std::optional<int> numPages{1}; | |
std::optional<int> page{1}; | |
static QueryMeta fetch(const std::string& apiUrl); | |
}; | |
// clang-format off | |
template <> struct glz::meta<ResultMeta> { | |
using T = ResultMeta; | |
static constexpr auto value = ::glz::object( | |
// Repository // AUR | |
"pkgbase", &T::base, "PackageBase", &T::base, | |
"pkgname", &T::name, "Name", &T::name, | |
"pkgver", &T::version, "Version", &T::version, | |
"pkgrel", &T::release, | |
"epoch", &T::epoch, | |
"pkgdesc", &T::description, "Description", &T::description, | |
"arch", &T::architecture, | |
"url", &T::url, "URL", &T::url, | |
"licenses", &T::licenses, "License", &T::licenses, | |
"groups", &T::groups, | |
"depends", &T::dependencies, "Depends", &T::dependencies, | |
"makedepends", &T::makeDependencies, "MakeDepends", &T::makeDependencies, | |
"checkdepends", &T::checkDependencies, "CheckDepends", &T::checkDependencies, | |
"optdepends", &T::optDependencies, "OptDepends", &T::optDependencies, | |
"provides", &T::provides, "Provides", &T::provides, | |
"conflicts", &T::conflicts, "Conflicts", &T::conflicts, | |
"replaces", &T::replaces, "Replaces", &T::replaces, | |
"repo", &T::repository, | |
"filename", &T::filename, | |
"compressed_size", &T::compressedSize, | |
"installed_size", &T::installedSize, | |
"build_date", &T::buildDate, | |
"last_update", &T::lastUpdated, "LastModified", &T::lastUpdated, | |
"flag_date", &T::outOfDateSince, "OutOfDate", &T::outOfDateSince, | |
"maintainers", &T::maintainers, "Maintainer", &T::maintainers, | |
"CoMaintainers", &T::maintainers, | |
"packager", &T::packager, "Submitter", &T::packager, | |
"FirstSubmitted", &T::firstSubmitted, | |
"ID", &T::ID, | |
"Keywords", &T::keywords, | |
"NumVotes", &T::voteCount, | |
"PackageBaseID", &T::baseID, | |
"Popularity", &T::popularity, | |
"URLPath", &T::urlPath | |
); | |
}; | |
template <> struct glz::meta<QueryMeta> { | |
using T = QueryMeta; | |
static constexpr auto value = ::glz::object( | |
"resultcount", skip{}, | |
"results", &T::results, | |
"type", skip{}, | |
"version", skip{}, | |
"limit", skip{}, | |
"valid", skip{}, | |
"num_pages", &T::numPages, | |
"page", &T::page | |
); | |
}; | |
// clang-format on | |
std::optional<SM9::Arch::Package> ResultMeta::getPackage() const { | |
SM9::Arch::Package package; | |
if (!name.has_value() || name.value().empty() || !base.has_value() || base.value().empty()) { | |
return std::nullopt; // Invalid package | |
} | |
package.base = base; | |
package.name = name; | |
if (version.has_value()) { | |
const auto hyphenPos = version->find('-'); | |
if (hyphenPos != std::string::npos) { | |
package.version = version->substr(0, hyphenPos); | |
package.release = version->substr(hyphenPos + 1); | |
} else { | |
package.version = version; | |
package.release = release; | |
} | |
} | |
package.release = release; | |
package.epoch = epoch; | |
package.description = description; | |
package.architecture = architecture; | |
package.url = url; | |
package.licenses = licenses; | |
package.groups = groups; | |
package.dependencies = dependencies; | |
package.makeDependencies = makeDependencies; | |
package.checkDependencies = checkDependencies; | |
package.optDependencies = optDependencies; | |
package.provides = provides; | |
package.conflicts = conflicts; | |
package.replaces = replaces; | |
package.repository = repository; | |
package.filename = filename; | |
package.compressedSize = compressedSize; | |
package.installedSize = installedSize; | |
if (buildDate.has_value()) { | |
package.buildDate = SM9::Formatting::Time::toPoint(buildDate.value()); | |
} | |
if (lastUpdated.has_value()) { | |
if (std::holds_alternative<std::string>(*lastUpdated)) { | |
package.lastUpdated = SM9::Formatting::Time::toPoint(std::get<std::string>(*lastUpdated)); | |
} else if (std::holds_alternative<int>(*lastUpdated)) { | |
package.lastUpdated = SM9::Formatting::Time::toPoint(std::get<int>(*lastUpdated)); | |
} | |
} | |
if (outOfDateSince.has_value()) { | |
if (std::holds_alternative<std::string>(*outOfDateSince)) { | |
package.outOfDateSince = SM9::Formatting::Time::toPoint(std::get<std::string>(*outOfDateSince)); | |
} else if (std::holds_alternative<int>(*outOfDateSince)) { | |
package.outOfDateSince = SM9::Formatting::Time::toPoint(std::get<int>(*outOfDateSince)); | |
} | |
} | |
if (maintainers.has_value()) { | |
if (std::holds_alternative<std::vector<std::string>>(*maintainers)) { | |
package.maintainers = std::get<std::vector<std::string>>(*maintainers); | |
} | |
if (std::holds_alternative<std::string>(*maintainers)) { | |
const auto& maintainer = std::get<std::string>(*maintainers); | |
if (!maintainer.empty()) { | |
if (!package.maintainers.has_value()) { | |
package.maintainers = std::vector<std::string>{}; | |
} | |
package.maintainers->push_back(maintainer); | |
} | |
} | |
} | |
package.packager = packager; | |
if (firstSubmitted.has_value()) { | |
package.firstSubmitted = SM9::Formatting::Time::toPoint(firstSubmitted.value()); | |
} | |
package.ID = ID; | |
package.keywords = keywords; | |
package.voteCount = voteCount; | |
package.baseID = baseID; | |
package.popularity = popularity; | |
package.urlPath = urlPath; | |
return package; | |
} | |
QueryMeta QueryMeta::fetch(const std::string& apiUrl) { | |
cpr::Response response = cpr::Get(cpr::Url{apiUrl}); | |
if (response.status_code != 200) { | |
throw std::runtime_error("Invalid response (HTTP Status: " + std::to_string(response.status_code) + ")"); | |
} | |
try { | |
const auto& responseText = response.text; | |
QueryMeta queryMeta; | |
const auto err = glz::read_json(queryMeta, responseText.c_str()); | |
if (err) { | |
throw std::runtime_error("Failed to read JSON: " + format_error(err, responseText)); | |
} | |
if (queryMeta.results.has_value()) { | |
queryMeta.resultCount = queryMeta.results->size(); | |
queryMeta.hasResults = queryMeta.resultCount > 0; | |
} | |
return queryMeta; | |
} catch (const std::exception& e) { | |
throw std::runtime_error("Failed to parse the JSON response: " + std::string(e.what()) + "\n" + apiUrl); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Package Package::fromJsonResult(const rapidjson::Value& result) { | |
Package package{}; | |
const SM9::JsonValue value(result); | |
package.base = value.getAString({"PackageBase", "pkgbase"}); | |
package.name = value.getAString({"Name", "pkgname"}); | |
const auto versionString = value.getAString({"Version", "pkgver"}); | |
const auto hyphenPos = versionString.find('-'); | |
if (hyphenPos != std::string::npos) { | |
package.version = versionString.substr(0, hyphenPos); | |
package.release = versionString.substr(hyphenPos + 1); | |
} else { | |
package.version = versionString; | |
package.release = value.getAString({"pkgrel"}); | |
} | |
package.epoch = value.getAnInt({"epoch"}); | |
package.description = value.getAString({"Description", "pkgdesc"}); | |
package.architecture | |
= value.getAString({"arch"}); // TODO: Retrieve this in another way (ie parse .SRCINFO or PKGBUILD) | |
package.url = value.getAString({"URL", "url"}); | |
package.licenses = value.getAnArrayOfStrings({"License", "licenses"}); | |
package.groups = value.getAnArrayOfStrings({"Groups", "groups"}); | |
package.dependencies = value.getAnArrayOfStrings({"Depends", "depends"}); | |
package.makeDependencies = value.getAnArrayOfStrings({"MakeDepends", "makedepends"}); | |
package.checkDependencies = value.getAnArrayOfStrings({"CheckDepends", "checkdepends"}); | |
package.optDependencies = value.getAnArrayOfStrings({"OptDepends", "optdepends"}); | |
package.provides = value.getAnArrayOfStrings({"Provides", "provides"}); | |
package.conflicts = value.getAnArrayOfStrings({"Conflicts", "conflicts"}); | |
package.replaces = value.getAnArrayOfStrings({"Replaces", "replaces"}); | |
package.repository = value.getAString({"repo", "repository"}, "AUR"); | |
package.filename = value.getAString({"filename"}); | |
package.buildOptions = value.getAString( | |
{"Options", "options"}); // TODO: Retrieve this in another way (ie parse .SRCINFO or PKGBUILD) | |
package.compressedSize = value.getAnInt({"compressed_size"}); | |
package.installedSize = value.getAnInt({"installed_size"}); | |
package.buildDate = value.getATimePoint({"build_date"}); | |
package.lastUpdated = value.getATimePoint({"last_update"}); | |
package.outOfDateSince = value.getATimePoint({"OutOfDate", "flag_date"}); | |
package.maintainers = value.getAnArrayOfStrings({"CoMaintainers", "maintainers"}); | |
const auto maintainer = value.getAString({"Maintainer"}); | |
if (!maintainer.empty()) { | |
package.maintainers.push_back(maintainer); | |
} | |
package.packager = value.getAString({"Submitter", "packager"}); | |
package.firstSubmitted = value.getATimePoint({"FirstSubmitted"}); | |
package.packageID = value.getAnInt({"ID"}); | |
package.keywords = value.getAnArrayOfStrings({"Keywords"}); | |
package.voteCount = value.getAnInt({"NumVotes"}); | |
package.basePackageID = value.getAnInt({"PackageBaseID"}); | |
package.popularity = value.getADouble({"PackageBaseID"}); | |
package.urlPath = value.getAString({"URLPath"}); | |
return package; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Package { | |
public: | |
static Package fromJsonResult(const rapidjson::Value& result); | |
std::string base{}; | |
std::string name{}; | |
std::string version{}; | |
std::string release{}; | |
int epoch{}; | |
std::string description{}; | |
std::string architecture{}; | |
std::string url{}; | |
std::vector<std::string> licenses{}; | |
std::vector<std::string> groups{}; | |
std::vector<std::string> dependencies{}; | |
std::vector<std::string> makeDependencies{}; | |
std::vector<std::string> checkDependencies{}; | |
std::vector<std::string> optDependencies{}; | |
std::vector<std::string> provides{}; | |
std::vector<std::string> conflicts{}; | |
std::vector<std::string> replaces{}; | |
std::string repository{}; | |
std::string filename{}; | |
std::string buildOptions{}; | |
int compressedSize{}; | |
int installedSize{}; | |
std::chrono::system_clock::time_point buildDate{}; | |
std::chrono::system_clock::time_point lastUpdated{}; | |
std::chrono::system_clock::time_point outOfDateSince{}; | |
std::vector<std::string> maintainers{}; | |
std::string packager{}; | |
std::chrono::system_clock::time_point firstSubmitted{}; | |
int packageID{}; | |
std::vector<std::string> keywords{}; | |
int voteCount{}; | |
int basePackageID{}; | |
double popularity{}; | |
std::string urlPath{}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GNU Lesser General Public License | |
* Version 3, 29 June 2007 | |
* | |
* Copyright (C) 2023 Michael Bolden Jnr | |
* | |
* Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not | |
* allowed. | |
* | |
* This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU | |
* General Public License. | |
* | |
* --------------------------------------------------------------------------------------------------------------------- | |
* | |
* This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General | |
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any | |
* later version. | |
* | |
* This software 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 Lesser General Public License for more | |
* details. | |
* | |
* You should have received a copy of the GNU Lesser General Public License along with this program. If not, see | |
* <http://www.gnu.org/licenses/>. | |
* | |
*/ | |
#include "libSM9/Time.hpp" | |
#include <iostream> | |
#include <regex> | |
#include <sstream> | |
#include <stdexcept> | |
namespace SM9 { | |
std::string Time::pointToString(const std::chrono::system_clock::time_point& timePoint, const std::string& format) { | |
return epochToString(pointToEpoch(timePoint), format); | |
} | |
int Time::pointToEpoch(const std::chrono::system_clock::time_point& timePoint) { | |
return std::chrono::duration_cast<std::chrono::seconds>(timePoint.time_since_epoch()).count(); | |
} | |
std::string Time::epochToString(const std::time_t& epochTime, const std::string& format) { | |
if (epochTime == std::time_t(0)) { | |
return ""; | |
} | |
std::stringstream ss; | |
ss << std::put_time(std::gmtime(&epochTime), format.c_str()); | |
return ss.str(); | |
} | |
std::string Time::epochToString(const int& epochTime, const std::string& format) { | |
return epochToString(static_cast<std::time_t>(epochTime), format); | |
} | |
std::chrono::system_clock::time_point Time::toPoint(const std::string& timestamp) { | |
const std::regex isoFormatPattern(R"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z)"); | |
const std::regex numericFormatPattern("\\d+"); | |
if (std::regex_match(timestamp, isoFormatPattern)) { | |
std::tm timeInfo = {}; | |
std::istringstream ss(timestamp); | |
ss >> std::get_time(&timeInfo, "%Y-%m-%dT%H:%M:%S"); | |
if (!ss.fail()) { | |
long long milliseconds = 0; | |
std::size_t dotPos = timestamp.find('.'); | |
if (dotPos != std::string::npos) { | |
milliseconds = std::stoll(timestamp.substr(dotPos + 1)); | |
} | |
auto seconds = std::chrono::seconds(std::mktime(&timeInfo)); | |
auto millisecondsDuration = std::chrono::milliseconds(milliseconds); | |
return std::chrono::system_clock::time_point(seconds + millisecondsDuration); | |
} | |
} else if (std::regex_match(timestamp, numericFormatPattern)) { | |
return toPoint(std::stoi(timestamp)); | |
} | |
throw std::invalid_argument("Invalid timestamp format: " + timestamp); | |
} | |
std::chrono::system_clock::time_point Time::toPoint(const int& epochTime) { | |
return std::chrono::system_clock::from_time_t(static_cast<std::time_t>(epochTime)); | |
} | |
} // namespace SM9 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GNU Lesser General Public License | |
* Version 3, 29 June 2007 | |
* | |
* Copyright (C) 2023 Michael Bolden Jnr | |
* | |
* Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not | |
* allowed. | |
* | |
* This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU | |
* General Public License. | |
* | |
* --------------------------------------------------------------------------------------------------------------------- | |
* | |
* This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General | |
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any | |
* later version. | |
* | |
* This software 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 Lesser General Public License for more | |
* details. | |
* | |
* You should have received a copy of the GNU Lesser General Public License along with this program. If not, see | |
* <http://www.gnu.org/licenses/>. | |
* | |
*/ | |
#pragma once | |
#include <chrono> | |
#include <string> | |
namespace SM9 { | |
struct Time { | |
static std::string pointToString( | |
const std::chrono::system_clock::time_point& timePoint, const std::string& format = "%d-%m-%Y %H:%M:%S"); | |
static int pointToEpoch(const std::chrono::system_clock::time_point& timePoint); | |
static std::string epochToString(const std::time_t& epochTime, const std::string& format = "%d-%m-%Y %H:%M:%S"); | |
static std::string epochToString(const int& epochTime, const std::string& format = "%d-%m-%Y %H:%M:%S"); | |
static std::chrono::system_clock::time_point toPoint(const std::string& timestamp); | |
static std::chrono::system_clock::time_point toPoint(const int& epochTime); | |
}; | |
} // namespace SM9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment