move headers to include/mcc to match duild and deploy configurations
move mcc_bsplines.h from fitpack to include/mcc rewrite CMakeLists.txt to incorporate these changes
This commit is contained in:
775
include/mcc/mcc_serializer.h
Normal file
775
include/mcc/mcc_serializer.h
Normal file
@@ -0,0 +1,775 @@
|
||||
#pragma once
|
||||
|
||||
#include "mcc_coordinate.h"
|
||||
#include "mcc_serialization_common.h"
|
||||
|
||||
namespace mcc::impl
|
||||
{
|
||||
|
||||
enum class MccSerializerErrorCode : int {
|
||||
ERROR_OK,
|
||||
ERROR_UNDERLYING_SERIALIZER,
|
||||
ERROR_INVALID_EPOCH,
|
||||
ERROR_COORD_TRANSFORM
|
||||
};
|
||||
|
||||
} // namespace mcc::impl
|
||||
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
class is_error_code_enum<mcc::impl::MccSerializerErrorCode> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
namespace mcc::impl
|
||||
{
|
||||
|
||||
// error category
|
||||
struct MccSerializerCategory : public std::error_category {
|
||||
MccSerializerCategory() : std::error_category() {}
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
return "MCC-SERIALIZER-ERR-CATEGORY";
|
||||
}
|
||||
|
||||
std::string message(int ec) const
|
||||
{
|
||||
MccSerializerErrorCode err = static_cast<MccSerializerErrorCode>(ec);
|
||||
|
||||
switch (err) {
|
||||
case MccSerializerErrorCode::ERROR_OK:
|
||||
return "OK";
|
||||
case MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER:
|
||||
return "error returned by underlying serializer";
|
||||
case MccSerializerErrorCode::ERROR_INVALID_EPOCH:
|
||||
return "invalid coordinate epoch";
|
||||
case MccSerializerErrorCode::ERROR_COORD_TRANSFORM:
|
||||
return "coordinates transformation error";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const MccSerializerCategory& get()
|
||||
{
|
||||
static const MccSerializerCategory constInst;
|
||||
return constInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline std::error_code make_error_code(MccSerializerErrorCode ec)
|
||||
{
|
||||
return std::error_code(static_cast<int>(ec), MccSerializerCategory::get());
|
||||
}
|
||||
|
||||
|
||||
/* BASE SERIALIZER CLASS (FOR IMPLEMENTATIONS BELOW) */
|
||||
|
||||
struct MccSerializerBase : mcc_serializer_interface_t<MccError> {
|
||||
virtual ~MccSerializerBase() = default;
|
||||
|
||||
using typename mcc_serializer_interface_t<MccError>::error_t;
|
||||
|
||||
protected:
|
||||
MccSerializerBase() = default;
|
||||
|
||||
enum CoordType { CO_LON, CO_LAT };
|
||||
|
||||
static void addElemDelimiter(traits::mcc_output_char_range auto& output,
|
||||
mcc_serialization_params_c auto const& params)
|
||||
{
|
||||
std::format_to(std::back_inserter(output), "{}", params.elem_delim);
|
||||
}
|
||||
|
||||
|
||||
static void addSeqDelimiter(traits::mcc_output_char_range auto& output,
|
||||
mcc_serialization_params_c auto const& params)
|
||||
{
|
||||
std::format_to(std::back_inserter(output), "{}", params.seq_delim);
|
||||
}
|
||||
|
||||
|
||||
// set serialized angle format according to coordinates pair format and type of
|
||||
// serializing mcc_coord_pair_c::pairKind
|
||||
template <MccCoordPairKind PAIRKIND, CoordType TYPE = MccSerializerBase::CO_LON>
|
||||
static void angleFormatFromCoordPairType(mcc_serialization_params_c auto& pars)
|
||||
{
|
||||
if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_DEGREES) {
|
||||
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES;
|
||||
} else { // format to sexagesimal form according to celestial coordinate type
|
||||
if constexpr (TYPE == MccSerializerBase::CO_LON) {
|
||||
if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGDEG) {
|
||||
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
|
||||
} else if (pars.coordpair_format == MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG) {
|
||||
if constexpr (PAIRKIND == MccCoordPairKind::COORDS_KIND_AZZD ||
|
||||
PAIRKIND == MccCoordPairKind::COORDS_KIND_AZALT ||
|
||||
PAIRKIND == MccCoordPairKind::COORDS_KIND_XY ||
|
||||
PAIRKIND == MccCoordPairKind::COORDS_KIND_GENERIC) { // azimuth is in degrees
|
||||
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
|
||||
} else { // RA or HA
|
||||
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS;
|
||||
}
|
||||
} else {
|
||||
// !!!!!!!!!!!!!!!!!!
|
||||
}
|
||||
} else { // Y-coordinates (co-latitude one, DEC, ALT, ZD, generic X) is always in degrees for celestial
|
||||
// point
|
||||
pars.angle_format = MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VT, typename R>
|
||||
requires(std::ranges::input_range<R> && std::same_as<VT, std::ranges::range_value_t<R>>)
|
||||
static error_t serializeRange(mcc_serializer_c auto& sr,
|
||||
R const& r,
|
||||
traits::mcc_output_char_range auto& output,
|
||||
mcc_serialization_params_c auto const& params)
|
||||
{
|
||||
size_t i = 0, N = std::ranges::size(r);
|
||||
|
||||
for (auto const& el : r) {
|
||||
auto err = sr(output, el, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
if (++i < N) {
|
||||
// MccSerializerBase::addSeqDelimiter(output, params);
|
||||
MccSerializerBase::addElemDelimiter(output, params);
|
||||
}
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* MAIN (FALLBACK) TEMPLATED IMPLEMENTATION */
|
||||
|
||||
template <typename VT>
|
||||
struct MccSerializer : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-FALLBACK-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
if constexpr (std::convertible_to<VT, std::string>) {
|
||||
std::string s = value;
|
||||
std::ranges::copy(s, std::back_inserter(output));
|
||||
// auto err = MccSerializer<std::string>{}(output, static_cast<std::string>(value), params);
|
||||
// if (err) {
|
||||
// return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
// }
|
||||
} else if constexpr (std::ranges::range<VT>) {
|
||||
using value_t = std::remove_cv_t<std::ranges::range_value_t<VT>>;
|
||||
|
||||
// special range (character sequence)
|
||||
if constexpr (std::same_as<value_t, char>) {
|
||||
std::ranges::copy(value, std::back_inserter(output));
|
||||
} else {
|
||||
MccSerializer<value_t> sr;
|
||||
|
||||
return MccSerializerBase::serializeRange<value_t>(sr, value, output, params);
|
||||
}
|
||||
} else if constexpr (std::formattable<VT, char>) {
|
||||
std::format_to(std::back_inserter(output), "{}", value);
|
||||
} else {
|
||||
static_assert(false, "UNSUPPORTED TYPE!!!");
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* SPECIALIZATION FOR THE SOME CONCEPTS */
|
||||
|
||||
|
||||
template <traits::mcc_time_duration_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
virtual ~MccSerializer() = default;
|
||||
|
||||
constexpr static std::string_view serializerName{"MCC-TIME-DURATION-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
std::format_to(std::back_inserter(output), "{}", value.count());
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* std::chrono::sys_time variants and its sequence */
|
||||
|
||||
template <traits::mcc_systime_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
virtual ~MccSerializer() = default;
|
||||
|
||||
constexpr static std::string_view serializerName{"MCC-SYSTIME-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
// std::vformat_to(std::back_inserter(output), params.systime_format, std::make_format_args(value));
|
||||
auto tp = std::chrono::round<std::chrono::milliseconds>(value);
|
||||
std::vformat_to(std::back_inserter(output), params.systime_format, std::make_format_args(tp));
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename VT>
|
||||
requires(!std::is_arithmetic_v<VT> && mcc_angle_c<VT>)
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-ANGLE-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
double v = (double)value; // radians (see mcc_angle_c concept)
|
||||
std::string sgm;
|
||||
|
||||
switch (params.angle_format) {
|
||||
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_DEGREES: {
|
||||
v *= MCC_RADS_TO_DEGRESS;
|
||||
std::string_view fmt = "{:." + std::to_string(params.angle_prec.decimals) + "f}";
|
||||
std::vformat_to(std::back_inserter(output), fmt, std::make_format_args(v));
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
// return MccSerializer<double>{}(output, v, params);
|
||||
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_DEGS:
|
||||
if (params.norm_sxgm) {
|
||||
sgm = utils::rad2sxg<true>(v, false, params.angle_prec.deg_prec);
|
||||
} else {
|
||||
sgm = utils::rad2sxg<false>(v, false, params.angle_prec.deg_prec);
|
||||
}
|
||||
|
||||
break;
|
||||
case MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS:
|
||||
if (params.norm_sxgm) {
|
||||
sgm = utils::rad2sxg<true>(v, true, params.angle_prec.hour_prec);
|
||||
} else {
|
||||
sgm = utils::rad2sxg<false>(v, true, params.angle_prec.hour_prec);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto err = MccSerializer<std::string>{}(output, sgm, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <mcc_coord_epoch_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-COORD-EPOCH-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
double jd;
|
||||
|
||||
switch (params.timepoint_format) {
|
||||
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_DATE: {
|
||||
auto tp = value.UTC();
|
||||
auto err = MccSerializer<decltype(tp)>{}(output, tp, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
};
|
||||
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_JEPOCH: {
|
||||
auto ep = value.JEpoch();
|
||||
auto err = MccSerializer<decltype(ep)>{}(output, ep, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
} break;
|
||||
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_JD:
|
||||
jd = value.MJD() + MCC_J2000_MJD;
|
||||
break;
|
||||
case MccTimePointFormat::MCC_TIMEPOINT_FORMAT_MJD:
|
||||
jd = value.MJD();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
auto err = MccSerializer<double>{}(output, jd, params);
|
||||
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <mcc_coord_pair_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-COORD-PAIR-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
auto pars = params;
|
||||
|
||||
// pars.norm_sxgm = true;
|
||||
// pars.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
|
||||
// X-coordinate
|
||||
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LON>(pars);
|
||||
|
||||
auto err = MccSerializer<MccAngle>{}(output, value.x(), pars);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, params);
|
||||
|
||||
pars.norm_sxgm = false; // do not normalize co-latitude angle
|
||||
|
||||
// Y-coordinate
|
||||
MccSerializerBase::angleFormatFromCoordPairType<VT::pairKind, MccSerializerBase::CO_LAT>(pars);
|
||||
|
||||
err = MccSerializer<MccAngle>{}(output, value.y(), pars);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, params);
|
||||
|
||||
// epoch
|
||||
auto ep = value.epoch();
|
||||
auto ep_err = MccSerializer<decltype(ep)>{}(output, ep, params);
|
||||
if (ep_err) {
|
||||
return mcc_deduced_err(ep_err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, params);
|
||||
|
||||
// pair kind
|
||||
auto pk_err = MccSerializer<std::string_view>{}(output, MccCoordPairKindToStr(VT::pairKind), params);
|
||||
if (pk_err) {
|
||||
return mcc_deduced_err(pk_err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <mcc_skypoint_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-SKYPOINT-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
auto serialize_cpair = [&]<typename T>(T& cp) -> error_t {
|
||||
auto ccte_err = value.to(cp);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
auto err = MccSerializer<T>{}(output, cp, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
};
|
||||
|
||||
switch (value.pairKind()) {
|
||||
case MccCoordPairKind::COORDS_KIND_RADEC_ICRS: {
|
||||
MccSkyRADEC_ICRS cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_RADEC_OBS: {
|
||||
MccSkyRADEC_OBS cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_RADEC_APP: {
|
||||
MccSkyRADEC_APP cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_HADEC_OBS: {
|
||||
MccSkyHADEC_OBS cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_HADEC_APP: {
|
||||
MccSkyHADEC_APP cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_AZZD: {
|
||||
MccSkyAZZD cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_AZALT: {
|
||||
MccSkyAZALT cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_XY: {
|
||||
MccGenXY cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
case MccCoordPairKind::COORDS_KIND_GENERIC: {
|
||||
MccGenXY cp;
|
||||
return serialize_cpair(cp);
|
||||
}
|
||||
default:
|
||||
return MccSerializerErrorCode::ERROR_COORD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <mcc_telemetry_data_c VT>
|
||||
struct MccSerializer<VT> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-TELEMETRY-DATA-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
// FORMAT: RA_OBS_MOUNT, DEC_OBS_MOUNT, RA_APP_MOUNT, DEC_APP_MOUNT, HA_APP_MOUNT, AZ_MOUNT, ZD_MOUNT,
|
||||
// REFR_CORR_MOUNT, ENC_X, ENC_Y, PCM_X, PCM_Y, RA_APP_TAG, DEC_APP_TAG, AZ_TAG, ZD_TAG, LAST, EO, TIMEPOINT,
|
||||
// STATUS
|
||||
|
||||
// NOTE: One must assume that the returned RA coordinates are in format of underlying celestial coordinate
|
||||
// transformation engine used in the mcc_skypoint_c class implementation. E.g. ERFA-library uses the
|
||||
// CIO-based representation of RA
|
||||
|
||||
auto pars_h = params;
|
||||
|
||||
auto pars_d = params;
|
||||
|
||||
|
||||
pars_h.norm_sxgm = true;
|
||||
pars_h.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
pars_d.norm_sxgm = true;
|
||||
pars_d.coordpair_format = MccSerializedCoordPairFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURDEG;
|
||||
|
||||
MccSkyRADEC_OBS rd_obs;
|
||||
MccSkyRADEC_APP rd_app;
|
||||
MccSkyHADEC_APP hd_app;
|
||||
MccSkyAZZD azzd;
|
||||
|
||||
// quantities in hour representation
|
||||
MccSerializerBase::angleFormatFromCoordPairType<MccCoordPairKind::COORDS_KIND_RADEC_ICRS,
|
||||
MccSerializerBase::CO_LON>(pars_h);
|
||||
|
||||
// quantities in degree representation
|
||||
MccSerializerBase::angleFormatFromCoordPairType<MccCoordPairKind::COORDS_KIND_RADEC_ICRS,
|
||||
MccSerializerBase::CO_LON>(pars_d);
|
||||
|
||||
MccSerializer<MccAngle> ang_sr;
|
||||
|
||||
// RA_OBS_MOUNT, DEC_OBS_MOUNT
|
||||
auto ccte_err = value.mountPos.toAtSameEpoch(rd_obs);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
auto err = ang_sr(output, rd_obs.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_obs.y(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// RA_APP_MOUNT, DEC_APP_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(rd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, rd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_app.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// HA_APP_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(hd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, hd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// AZ_MOUNT, ZD_MOUNT
|
||||
ccte_err = value.mountPos.toAtSameEpoch(azzd);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, azzd.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, azzd.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// refraction correction
|
||||
|
||||
MccAngle ang;
|
||||
ccte_err = value.mountPos.refractCorrection(&ang);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// encoder X and Y
|
||||
|
||||
err = ang_sr(output, value.hwState.XY.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, value.hwState.XY.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// PCM X and Y
|
||||
|
||||
err = ang_sr(output, value.pcmCorrection.pcmX, pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, value.pcmCorrection.pcmY, pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// RA_APP_TAG, DEC_APP_TAG
|
||||
ccte_err = value.targetPos.toAtSameEpoch(rd_app);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, rd_app.x(), pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, rd_app.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// AZ_TAG, ZD_TAG
|
||||
ccte_err = value.targetPos.toAtSameEpoch(azzd);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, azzd.x(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
err = ang_sr(output, azzd.y(), pars_d);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// LAST, local apparent sideral time
|
||||
|
||||
ccte_err = value.mountPos.appSideralTime(&ang, true);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// EO, equation of origins
|
||||
|
||||
ccte_err = value.mountPos.EO(&ang);
|
||||
if (ccte_err) {
|
||||
return mcc_deduced_err(ccte_err, MccSerializerErrorCode::ERROR_COORD_TRANSFORM);
|
||||
}
|
||||
|
||||
err = ang_sr(output, ang, pars_h);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
// coordinates epoch
|
||||
|
||||
auto ep_err = MccSerializer<MccCelestialCoordEpoch>{}(output, value.mountPos.epoch(), pars_d);
|
||||
if (ep_err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
MccSerializerBase::addElemDelimiter(output, pars_h);
|
||||
|
||||
|
||||
// status (it must be formattable, see mcc_concepts.h)
|
||||
|
||||
auto st_err =
|
||||
MccSerializer<decltype(value.hwState.movementState)>{}(output, value.hwState.movementState, pars_d);
|
||||
if (st_err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <>
|
||||
struct MccSerializer<MccSerializedCoordPairFormat> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-COORDPAIR-FORMAT-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
MccSerializedCoordPairFormat const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
std::ranges::copy(MccSerializedCoordPairFormatToStr(value), std::back_inserter(output));
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct MccSerializer<MccSerializedAngleFormatPrec> : MccSerializerBase {
|
||||
constexpr static std::string_view serializerName{"MCC-ANGLE-FORMAT-PREC-SERIALIZER"};
|
||||
|
||||
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||
MccSerializedAngleFormatPrec const& value,
|
||||
ParamsT const& params = mcc_serialization_params_t{})
|
||||
{
|
||||
auto err = MccSerializer<decltype(value.hour_prec)>{}(output, value.hour_prec, params);
|
||||
if (!err) {
|
||||
auto err = MccSerializer<decltype(value.deg_prec)>{}(output, value.deg_prec, params);
|
||||
if (!err) {
|
||||
auto err = MccSerializer<decltype(value.decimals)>{}(output, value.decimals, params);
|
||||
if (err) {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
} else {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
} else {
|
||||
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return MccSerializerErrorCode::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static_assert(mcc_serializer_c<MccSerializer<MccAngle>>, "!!!");
|
||||
|
||||
} // namespace mcc::impl
|
||||
Reference in New Issue
Block a user