Skip to content

nodeluna/ljson

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ljson is an easy to use header only json library for c++

requirements

  • compiler that supports c++20
  • gcc 13 or clang 17

usage

header-only

  • clone the repo
  • add the include/ directory to your build system
  • include <ljson.hpp>

c++20 modules

  • clone the repo
  • add the mod/ and include/ directory to your build system
  • import ljson;

check out the example at test/import_ljson/ to see how to use the library as a module in cmake

tutorial

reading and writing to files

#include <ljson.hpp>
#include <exception>

int main() {
	std::filesystem::path path_to_file = "meow";

	try {
		ljson::node node = ljson::parser::parse(path_to_file);
		std::pair<char, int> indent_config = {'\t', 2}; // you can specifiy tab/space here and it's count
		node.dump_to_stdout(indent_config);
		node.dump_to_stdout(); // not specifiying defaults to {' ', 4}
		node.dump_to_file("new_file.json" /*, indent_config */);


	} catch (const ljson::error& error) {
		// parsing error, JSON syntax error
		// handle error
	}
  
}

exception free parsing

#include <ljson.hpp>
#include <print>

int main() {
	std::filesystem::path path_to_file = "meow";
	ljson::expected<ljson::node, ljson::error> node = ljson::parser::try_parse(path_to_file);
	if (not node)
	{
		// handle error
		std::println("{}", node.error().message());
	}
	else
	{
		// parsed successfully
	}
  
}

accessing and changing/setting values

#include <ljson.hpp>
#include <exception>

int main() {
	std::filesystem::path path_to_file = "meow";

	// making a json object
	ljson::node j2 = {
		 {"simple_key", "meow_value"},
		 {"array_key", ljson::node({ // ljson::node() can hold an object, array's values or a simple value
				 "arr_key1",
				 "arr_key2",
				 "arr_key3",
				 "arr_key4",
				 "arr_key5",
				 })},
		 {"object_key", ljson::node({
				 {"obj_key1", "value1"},
				 {"obj_key2", "value2"},
				 {"obj_key3", "value3"},
				 })},
	};

	try {
		ljson::node node = ljson::parser::parse(path_to_file);

		// this function adds an object to a key
		node.insert("new_object", j2);

		ljson::node new_node = node.at("object_key").at("nested_key"); // getting the value of nested_key
												 // this function can throw if the key doesn't exist

		// to check if the key exists or not
		if (node.contains("object_key")) {
			new_node = node.at("object_key");
			if (new_node.contains("nested_key")) {
				new_node = new_node.at("nested_key");

				// to change the value, it can be done this way
				new_node.set("new_value_for_nested_key");
				// or this way
				new_node = "new_value_for_nested_key";
			}
		}

		// this function adds an object to an array
		node.at("object").at("array_key").push_back(j2);

		// this function adds a value to an array
		node.at("object").at("array_key").push_back("new_array_value");

		// to access an index inside an array pass a size_t to the .at(index) function
		new_node = node.at("object").at("array_key").at(0); 

		// to chage its value
		std::expected<std::monostate, ljson::error> ok = new_node.set("changed_value");
		if (not ok) {
			std::println("err: {}", ok.error().message()); // ok.error().value() == ljson::error_type::wrong_type
		}
		new_node.set(true);
		new_node.set(12);
		new_node.set(ljson::null); // set its value to 'null'

		node.dump_to_file("new_file.json"); // write the new changes


	} catch (const ljson::error& error) {
		// parsing error, JSON syntax error
		// handle error
	}
}

exception free key access

#include <ljson.hpp>
#include <exception>

int main() {
	// making a json object
	ljson::node j2 = {
		 {"simple_key", "meow_value"},
		 {"array_key", ljson::node({ // ljson::node() can hold an object, array's values or a simple value
				 "arr_key1",
				 "arr_key2",
				 "arr_key3",
				 "arr_key4",
				 "arr_key5",
				 })},
		 {"object_key", ljson::node({
				 {"obj_key1", "value1"},
				 {"obj_key2", "value2"},
				 {"obj_key3", "value3"},
				 })},
	};

	// this function adds an object to a key
	node.insert("new_object", j2);

	ljson::expected<std::reference_wrapper<ljson::node>, ljson::error> simple_node = node.try_at("simple_key");
	if (simple_node)
	{
		ljson::node& node_ref = simple_node.value().get();
		ljson::expected<std::string, ljson::error> maybe_string = node_ref.try_as_string();
		if (maybe_string)
		{
			std::println("{}", maybe_value.value()); // prints: meow_value
		}
	}
}

casting to a json array and iteration

#include <ljson.hpp>
#include <exception>

int main() {
	std::filesystem::path path_to_file = "meow";

	try {
		// parse the file
		ljson::node new_node = node.at("key").at("array");
		if (new_node.is_array()) {
			// this function can throw if the internal type isn't an json array
			std::shared_ptr<ljson::array> array = new_node.as_array();

			for (ljson::node& element : *array) {
				if (element.is_value()) {
					std::println("array element: {}, type name: {}",
						element->as_value().stringify(), element->as_value().type_name());
				}
			}
		}


	} catch (const ljson::error& error) {
		// parsing error, JSON syntax error
		// handle error
	}
  
}

casting to a json object and iteration

#include <ljson.hpp>
#include <exception>

int main() {
	std::filesystem::path path_to_file = "meow";

	try {
		// parse the file
		ljson::node new_node = node.at("key").at("object");
		if (new_node.is_object()) {
			// this function can throw if the internal type isn't a json object
			std::shared_ptr<ljson::object> object = new_node.as_object();

			for (auto& [key, node] : *object) {
				if (node.is_value()) {
					std::println("object key: {} element: {}, type name: {}", key
						node->as_value().stringify(), node->as_value().type_name());
				}
			}
		}


	} catch (const ljson::error& error) {
		// parsing error, JSON syntax error
		// handle error
	}
  
}

exception free casting

#include <ljson.hpp>

// add "try_" in front of any casting method that throws

int main()
{
	ljson::node node;

	// throws
	int number = node.as_integer();
	std::string number = node.as_string();


	// doesn't throw
	ljson::expected<int, ljson::error> number = node.try_as_integer();
	ljson::expected<std::string, ljson::error> number = node.try_as_string();
}

inserting std library containers into a node

#include <ljson.hpp>
#include <exception>

int main() {
	std::filesystem::path path_to_file = "meow";

	try {
		// parse the file

		std::map<std::string, std::string> object = {
				{"meow_key", "value1"},
				{"meow_key2", "value2"},
		};
		std::list<std::string> array = {"meow", "meoow"};


		if (node.is_object)
		{
			node.insert("array", array); // inserts an array to the value name "array"
			node.insert("object", object); // inserts an object to the value name "object"
		}
		else if (node.is_array())
		{
			node.push_back(array); // pushes back an array at the end of the array
			node.push_back(object); // pushes back an object at the end of the array
		}

	} catch (const ljson::error& error) {
		// parsing error, JSON syntax error
		// handle error
	}
  
}

author

nodeluna - [email protected]

license

Copyright 2025 nodeluna

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

special thanks to

About

an easy to use header only JSON library for C++20

Topics

Resources

License

Unknown, Apache-2.0 licenses found

Licenses found

Unknown
LICENSE
Apache-2.0
LICENSE.txt

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

No packages published

Languages