Skip to content

Commit

Permalink
Added support for complex metadata checks
Browse files Browse the repository at this point in the history
This commit is intended to demonstrate how complex checks (involving more
than one metadata entries) can be added if required.
  • Loading branch information
veloman-yunkan committed Mar 28, 2023
1 parent 5a584f9 commit ecbd62c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
71 changes: 70 additions & 1 deletion src/metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,59 @@ size_t getTextLength(const std::string& utf8EncodedString)
return icu::UnicodeString::fromUTF8(utf8EncodedString).length();
}

bool checkTextLanguage(const std::string& text, const std::string& langCode)
{
// TODO: check that text is in langCode's script
return true;
}

class MetadataComplexCheckBase
{
public:
const std::string description;
const MetadataComplexCheckBase* const prev;

public: // functions
explicit MetadataComplexCheckBase(const std::string& desc)
: description(desc)
, prev(last)
{
last = this;
}

virtual ~MetadataComplexCheckBase() = default;

virtual bool checkMetadata(const Metadata& m) const = 0;

static const MetadataComplexCheckBase* getLastCheck() { return last; }

private: // functions
static const MetadataComplexCheckBase* last;
};

const MetadataComplexCheckBase* MetadataComplexCheckBase::last = nullptr;

#define ADD_METADATA_COMPLEX_CHECK(DESC, CLSNAME) \
class CLSNAME : public MetadataComplexCheckBase \
{ \
public: \
CLSNAME() : MetadataComplexCheckBase(DESC) {} \
bool checkMetadata(const Metadata& data) const override; \
}; \
\
const CLSNAME CONCAT(obj, CLSNAME); \
\
bool CLSNAME::checkMetadata(const Metadata& data) const \
/* should be followed by the check body */



#define CONCAT(X, Y) X##Y
#define GENCLSNAME(UUID) CONCAT(MetadataComplexCheck, UUID)

#define METADATA_ASSERT(DESC) ADD_METADATA_COMPLEX_CHECK(DESC, GENCLSNAME(__LINE__))


#include "metadata_constraints.cpp"

} // unnamed namespace
Expand Down Expand Up @@ -124,13 +177,29 @@ Metadata::Errors Metadata::checkSimpleConstraints() const
return errors;
}

Metadata::Errors Metadata::checkComplexConstraints() const
{
Errors errors;
const MetadataComplexCheckBase* c = MetadataComplexCheckBase::getLastCheck();
for ( ; c != nullptr ; c = c->prev ) {
if ( ! c->checkMetadata(*this) ) {
errors.push_back(c->description);
}
}
return errors;
}

Metadata::Errors Metadata::check() const
{
Errors e = checkMandatoryMetadata();
if ( !e.empty() )
return e;

return checkSimpleConstraints();
e = checkSimpleConstraints();
if ( !e.empty() )
return e;

return checkComplexConstraints();
}

} // namespace zim
1 change: 1 addition & 0 deletions src/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Metadata
private: // functions
Errors checkMandatoryMetadata() const;
Errors checkSimpleConstraints() const;
Errors checkComplexConstraints() const;

private: // data
std::map<std::string, std::string> data;
Expand Down
13 changes: 13 additions & 0 deletions src/metadata_constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,16 @@ const Metadata::ReservedMetadataTable reservedMetadataInfoTable = {
PNG_REGEXP
},
};

METADATA_ASSERT("LongDescription shouldn't be shorter than Description")
{
return !data.has("LongDescription")
|| data["LongDescription"].size() >= data["Description"].size();
}

METADATA_ASSERT("Description must be in the language of the ZIM file")
{
const auto lang = data["Language"];
const auto description = data["Description"];
return checkTextLanguage(description, lang);
}
13 changes: 13 additions & 0 deletions test/metadata-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,16 @@ TEST(Metadata, regexpConstraints)
m.set("Language", "fre,nch");
ASSERT_TRUE(m.valid());
}

TEST(Metadata, complexConstraints)
{
zim::Metadata m = makeValidMetadata();
m.set("Description", "Short description");
m.set("LongDescription", "Long description");
ASSERT_FALSE(m.valid());
ASSERT_EQ(m.check(),
zim::Metadata::Errors({
"LongDescription shouldn't be shorter than Description"
})
);
}

0 comments on commit ecbd62c

Please sign in to comment.