From 60b2220b975596df0fe1dfea4155717d35684453 Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 31 Aug 2023 17:06:02 -0300 Subject: [PATCH] some more early thoughts about syntax --- src/CMakeLists.txt | 2 + src/dependency.cpp | 25 ++++++++++++ src/dependency.h | 31 +++++++++++++++ src/main.cpp | 1 + src/project.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++-- src/project.h | 11 ++++++ test/mason.json | 10 ++++- 7 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 src/dependency.cpp create mode 100644 src/dependency.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1a2e8d..73d73e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,12 @@ set(SOURCES main.cpp project.cpp + dependency.cpp ) set(HEADERS project.h + dependency.cpp ) target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) diff --git a/src/dependency.cpp b/src/dependency.cpp new file mode 100644 index 0000000..c1aec3c --- /dev/null +++ b/src/dependency.cpp @@ -0,0 +1,25 @@ +#include "dependency.h" + +Dependency::Dependency( + const std::string& path, + Type type, + const std::optional& name, + const std::optional& version +): + path(path), + type(type), + name(name), + version(version) +{} + +Dependency::Type Dependency::getType() const { + return type; +} + +std::optional Dependency::getName() const { + return name; +} + +std::optional Dependency::getVersion() const { + return version; +} diff --git a/src/dependency.h b/src/dependency.h new file mode 100644 index 0000000..0cea750 --- /dev/null +++ b/src/dependency.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +class Dependency { +public: + enum class Type { + automatic, + simple, + mason + }; + + Dependency( + const std::string& path, + Type type = Type::automatic, + const std::optional& name = std::nullopt, + const std::optional& version = std::nullopt + ); + + Type getType() const; + std::optional getName() const; + std::optional getVersion() const; + + const std::string path; + +private: + Type type; + std::optional name; + std::optional version; +}; diff --git a/src/main.cpp b/src/main.cpp index a3aedf1..f3d76b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ int main(int argc, char *argv[]) { return -1; } else { std::cout << "successfully parsed project " << root.getName() << std::endl; + std::cout << "dependencies count is " << root.dependenciesCount() << std::endl; } diff --git a/src/project.cpp b/src/project.cpp index d2a2e2b..45531ef 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1,15 +1,26 @@ #include "project.h" -#include #include #include +using json = nlohmann::json; + constexpr std::string_view entry("mason.json"); +std::map types({ + {"simple", Dependency::Type::simple}, + {"none", Dependency::Type::simple}, + {"mason", Dependency::Type::mason}, + {"auto", Dependency::Type::automatic}, + {"automatic", Dependency::Type::automatic} +}); + Project::Project(const std::filesystem::path& location): location(location), status(Status::unknown), - name() + name(), + logStorage(), + dependencies() {} bool Project::read() { @@ -32,9 +43,17 @@ bool Project::read() { return false; } + json data; try { - nlohmann::json data = nlohmann::json::parse(file); - name = data.at("name"); + data = json::parse(file); + } catch (const json::exception& e) { + log(e.what()); + status = Status::error; + return false; + } + + try { + parse(data); } catch (const std::exception& e) { log(e.what()); status = Status::error; @@ -44,6 +63,74 @@ bool Project::read() { return true; } +void Project::parse(const json& data) { + const json& nm = data.at("name"); + if (!nm.is_string()) + throw 1; + + name = nm; + + const json& dpd = data.at("dependencies"); + if (!dpd.is_array()) + throw 1; + + for (const json& dep : dpd) { + switch (dep.type()) { + case json::value_t::string: + createDepencencyFromString(dep); + break; + case json::value_t::object: + createDepencencyFromObject(dep); + break; + default: + throw 1; + } + } +} + +void Project::createDepencencyFromString(const std::string& entry) { + dependencies.emplace(entry, entry); +} + +void Project::createDepencencyFromObject(const nlohmann::json& entry) { + std::string url; + json::const_iterator itr = entry.find("url"); + if (itr == entry.end()) { + itr = entry.find("path"); + if (itr == entry.end()) + throw 1; + } + if (!itr->is_string()) + throw 1; + + url = *itr; + + std::optional name = std::nullopt; + itr = entry.find("name"); + if (itr != entry.end() && itr->is_string()) + name = *itr; + + std::optional version = std::nullopt; + itr = entry.find("version"); + if (itr != entry.end() && itr->is_string()) + version = *itr; + + Dependency::Type type = Dependency::Type::automatic; + itr = entry.find("type"); + if (itr != entry.end() && itr->is_string()) { + std::map::const_iterator titr = types.find(*itr); + if (titr != types.end()) + type = titr->second; + } + + dependencies.emplace(url, Dependency{url, type, name, version}); +} + +uint32_t Project::dependenciesCount() const { + return dependencies.size(); +} + + void Project::log(const std::string& message) const { logStorage.emplace_back(message); } diff --git a/src/project.h b/src/project.h index b7e02cb..1ea6195 100644 --- a/src/project.h +++ b/src/project.h @@ -4,6 +4,12 @@ #include #include #include +#include +#include + +#include + +#include "dependency.h" class Project { public: @@ -20,14 +26,19 @@ public: Status getStatus() const; Log getLog() const; std::string getName() const; + uint32_t dependenciesCount() const; private: void log(const std::string& message) const; + void parse(const nlohmann::json& json); + void createDepencencyFromString(const std::string& entry); + void createDepencencyFromObject(const nlohmann::json& entry); private: std::filesystem::path location; Status status; std::string name; mutable Log logStorage; + std::map dependencies; }; diff --git a/test/mason.json b/test/mason.json index e8de763..e6f5991 100644 --- a/test/mason.json +++ b/test/mason.json @@ -1,4 +1,12 @@ { "name" : "test", - "version" : "0.0.1" + "version" : "0.0.1", + "dependencies" : [ + "somePath", + "https://git.macaw.me/blue/mason.git", + { + "name" : "aProject", + "path" : "https://nowhere.to" + } + ] }