mu/lib/mu-data.hh

157 lines
3.7 KiB
C++

/*
** Copyright (C) 2017 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This library 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 2.1
** of the License, or (at your option) any later version.
**
** This library 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 library; if not, write to the Free
** Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*/
#ifndef __DATA_HH__
#define __DATA_HH__
#include <string>
#include <iostream>
#include <regex>
#include <utils/mu-utils.hh>
namespace Mu {
// class representing some data item; either a Value or a Range a Value can still be a Regex (but
// that's not a separate type here)
struct Data {
enum class Type { Value, Range };
virtual ~Data() = default;
Type type; /**< type of data */
std::string field; /**< full name of the field */
std::string prefix; /**< Xapian prefix for thef field */
unsigned id; /**< Xapian value no for the field */
protected:
Data(Type _type, const std::string& _field, const std::string& _prefix, unsigned _id)
: type(_type), field(_field), prefix(_prefix), id(_id)
{
}
};
/**
* operator<<
*
* @param os an output stream
* @param t a data type
*
* @return the updated output stream
*/
inline std::ostream&
operator<<(std::ostream& os, Data::Type t)
{
switch (t) {
case Data::Type::Value: os << "value"; break;
case Data::Type::Range: os << "range"; break;
default: os << "bug"; break;
}
return os;
}
/**
* Range type -- [a..b]
*/
struct Range : public Data {
/**
* Construct a range
*
* @param _field the field
* @param _prefix the xapian prefix
* @param _id xapian value number
* @param _lower lower bound
* @param _upper upper bound
*/
Range(const std::string& _field,
const std::string& _prefix,
unsigned _id,
const std::string& _lower,
const std::string& _upper)
:
Data(Data::Type::Range, _field, _prefix, _id), lower(_lower), upper(_upper)
{
}
std::string lower; /**< lower bound */
std::string upper; /**< upper bound */
};
/**
* Basic value
*
*/
struct Value : public Data {
/**
* Construct a Value
*
* @param _field the field
* @param _prefix the xapian prefix
* @param _id xapian value number
* @param _value the value
*/
Value(const std::string& _field,
const std::string& _prefix,
unsigned _id,
const std::string& _value,
bool _phrase = false)
: Data(Value::Type::Value, _field, _prefix, _id), value(_value), phrase(_phrase)
{
}
std::string value; /**< the value */
bool phrase;
};
/**
* operator<<
*
* @param os an output stream
* @param v a data ptr
*
* @return the updated output stream
*/
inline std::ostream&
operator<<(std::ostream& os, const std::unique_ptr<Data>& v)
{
switch (v->type) {
case Data::Type::Value: {
const auto bval = dynamic_cast<Value*>(v.get());
os << ' ' << quote(v->field) << ' ' << quote(utf8_flatten(bval->value));
if (bval->phrase)
os << " (ph)";
break;
}
case Data::Type::Range: {
const auto rval = dynamic_cast<Range*>(v.get());
os << ' ' << quote(v->field) << ' ' << quote(rval->lower) << ' '
<< quote(rval->upper);
break;
}
default: os << "unexpected type"; break;
}
return os;
}
} // namespace Mu
#endif /* __DATA_HH__ */