diff --git a/include/openPMD/auxiliary/JSON.hpp b/include/openPMD/auxiliary/JSON.hpp index 223dfbde87..26aa52281c 100644 --- a/include/openPMD/auxiliary/JSON.hpp +++ b/include/openPMD/auxiliary/JSON.hpp @@ -59,16 +59,58 @@ namespace json * users to overwrite default options, while keeping any other ones. * * @param defaultValue A string containing either a JSON or a TOML dataset. + * If the string begins with an `@`, the JSON/TOML dataset will be + * read from the filesystem at the specified path. * @param overwrite A string containing either a JSON or TOML dataset (does - * not need to be the same as `defaultValue`). + * not need to be the same as `defaultValue`). + * If the string begins with an `@`, the JSON/TOML dataset will be + * read from the filesystem at the specified path. * @return std::string The merged dataset, according to the above rules. If - * `defaultValue` was a JSON dataset, then as a JSON string, otherwise as a - * TOML string. + * `overwrite` was a JSON dataset, then as a JSON string, otherwise + * as a TOML string. */ std::string merge(std::string const &defaultValue, std::string const &overwrite); #if openPMD_HAVE_MPI + /** + * @brief Merge two JSON/TOML datasets into one. + * + * Merging rules: + * 1. If both `defaultValue` and `overwrite` are JSON/TOML objects, then the + * resulting JSON/TOML object will contain the union of both objects' + * keys. If a key is specified in both objects, the values corresponding + * to the key are merged recursively. Keys that point to a null value + * after this procedure will be pruned. + * 2. In any other case, the JSON/TOML dataset `defaultValue` is replaced in + * its entirety with the JSON/TOML dataset `overwrite`. + * + * Note that item 2 means that datasets of different type will replace each + * other without error. + * It also means that array types will replace each other without any notion + * of appending or merging. + * + * Possible use case: + * An application uses openPMD-api and wants to do the following: + * 1. Set some default backend options as JSON/TOML parameters. + * 2. Let its users specify custom backend options additionally. + * + * By using the json::merge() function, this application can then allow + * users to overwrite default options, while keeping any other ones. + * + * @param defaultValue A string containing either a JSON or a TOML dataset. + * If the string begins with an `@`, the JSON/TOML dataset will be + * read in parallel (using the MPI Communicator) + * from the filesystem at the specified path. + * @param overwrite A string containing either a JSON or TOML dataset (does + * not need to be the same as `defaultValue`). + * If the string begins with an `@`, the JSON/TOML dataset will be + * read in parallel (using the MPI Communicator) + * from the filesystem at the specified path. + * @return std::string The merged dataset, according to the above rules. If + * `overwrite` was a JSON dataset, then as a JSON string, otherwise + * as a TOML string. + */ std::string merge( std::string const &defaultValue, std::string const &overwrite, diff --git a/src/binding/python/Series.cpp b/src/binding/python/Series.cpp index 01cc836ba9..c4fd8119b8 100644 --- a/src/binding/python/Series.cpp +++ b/src/binding/python/Series.cpp @@ -421,10 +421,16 @@ users to overwrite default options, while keeping any other ones. Parameters: * default_value: A string containing either a JSON or a TOML dataset. + If the string begins with an `@`, the JSON/TOML dataset will be + read from the filesystem at the specified path. + An MPI communicator can be passed to read in parallel. * overwrite: A string containing either a JSON or TOML dataset (does not need to be the same as `defaultValue`). + If the string begins with an `@`, the JSON/TOML dataset will be + read from the filesystem at the specified path. + An MPI communicator can be passed to read in parallel. * returns: The merged dataset, according to the above rules. - If `defaultValue` was a JSON dataset, then as a JSON string, + If `overwrite` was a JSON dataset, then as a JSON string, otherwise as a TOML string. )END"[1]; diff --git a/test/JSONTest.cpp b/test/JSONTest.cpp index 46b2459e52..4d85fe705d 100644 --- a/test/JSONTest.cpp +++ b/test/JSONTest.cpp @@ -215,8 +215,8 @@ right = "val" }(); REQUIRE(json::merge(leftJson, rightJson) == resJson); - REQUIRE(json::merge(leftJson, rightToml) == resJson); - REQUIRE(sort_lines(json::merge(leftToml, rightJson)) == resToml); + REQUIRE(sort_lines(json::merge(leftJson, rightToml)) == resToml); + REQUIRE(json::merge(leftToml, rightJson) == resJson); REQUIRE(sort_lines(json::merge(leftToml, rightToml)) == resToml); } }