diff --git a/mcc/mcc_defaults.h b/mcc/mcc_defaults.h index 0893c60..ce2158e 100644 --- a/mcc/mcc_defaults.h +++ b/mcc/mcc_defaults.h @@ -504,9 +504,12 @@ static_assert(mcc_celestial_point_c, ""); static_assert(mcc_telemetry_data_c, ""); + /* DEFAULT SERIALIZER/DESERIALIZER FOR COORDINATE-RELATED CLASSES */ +static constexpr std::string_view MccCoordinateDefaultDelimiter{","}; + // base class class MccCoordinateDeserializer { @@ -536,7 +539,7 @@ public: } protected: - std::string _delimiter{","}; + std::string _delimiter{MccCoordinateDefaultDelimiter}; template std::vector splitToElements(IR&& bytes) @@ -629,7 +632,7 @@ protected: SerializedCoordFormat _currentFormat{CFMT_DEGREES}; SexagesimalCoordPrec _currentPrec{.hour_prec = 2, .deg_prec = 1}; - std::string _delimiter{","}; + std::string _delimiter{MccCoordinateDefaultDelimiter}; template void serializePairKindTimePoint(const T& value, OR& bytes) @@ -777,10 +780,131 @@ public: class MccEqtHrzCoordsSerializer : public MccCoordinateSerializer { + template + void operator()(const T& value, OR& bytes) + { + // output format: RA, DEC, HA, AZ, ZD, ALT, X, Y, pair-kind, time-point + // in the case of sexagesimal output X,Y coordinates will be interpretated + // according to value.pair_kind field + + if (_currentFormat == SerializedCoordFormat::CFMT_DEGREES) { + toDegrees(bytes, value.RA_APP, value.DEC_APP, value.HA, value.AZ, value.ZD, value.ALT, value.X, value.Y); + } else if (_currentFormat == SerializedCoordFormat::CFMT_SGM) { + toSexagesimalHour(bytes, value.RA_APP); + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + + toSexagesimalDeg(bytes, value.DEC_APP); + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + + toSexagesimalHour(bytes, value.HA); + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + + toSexagesimalDeg(bytes, value.AZ, value.ZD, value.ALT); + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + + switch (value.pair_kind) { + case MccCoordPairKind::COORDS_KIND_RADEC_ICRS: + case MccCoordPairKind::COORDS_KIND_RADEC_APP: + case MccCoordPairKind::COORDS_KIND_HADEC_APP: + toSexagesimalHour(bytes, value.X); + break; + default: + toSexagesimalDeg(bytes, value.X); + } + + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + toSexagesimalDeg(bytes, value.Y); + } else { + // !!!!! + } + + std::format_to(std::back_inserter(bytes), "{}", _delimiter); + + serializePairKindTimePoint(value, bytes); + } }; class MccEqtHrzCoordsDeserializer : public MccCoordinateDeserializer { + template + std::error_code operator()(IR&& bytes, T& value) + { + auto els = splitToElements(std::forward(bytes)); + } }; + + +/**/ + +static constexpr char MccCoordinateXFmt = 'x'; +static constexpr char MccCoordinateYFmt = 'y'; +static constexpr char MccCoordinateRA_ICRSFmt = 'R'; +static constexpr char MccCoordinateDEC_ICRSFmt = 'D'; +static constexpr char MccCoordinateRA_APPFmt = 'r'; +static constexpr char MccCoordinateDEC_APPFmt = 'd'; +static constexpr char MccCoordinateHAFmt = 'h'; +static constexpr char MccCoordinateAZFmt = 'a'; +static constexpr char MccCoordinateZDFmt = 'z'; +static constexpr char MccCoordinateALTFmt = 'A'; +static constexpr char MccCoordinateTMFmt = 't'; // time point +static constexpr char MccCoordinatePKFmt = 'p'; // pair kind + + } // namespace mcc + + +template +struct std::formatter { + std::vector fmt_order; + + template + constexpr ParseContext::iterator parse(ParseContext& ctx) + { + bool do_fmt = false; + + for (auto it = ctx.begin(); it != ctx.end(); ++it) { + if (*it == '%' && !do_fmt) { + do_fmt = true; + continue; + } else { + throw std::format_error("Invalid format argument for celestial point"); + } + + switch (*it) { + case mcc::MccCoordinateXFmt: + case mcc::MccCoordinateYFmt: + case mcc::MccCoordinateRA_ICRSFmt: + case mcc::MccCoordinateDEC_ICRSFmt: + case mcc::MccCoordinateRA_APPFmt: + case mcc::MccCoordinateDEC_APPFmt: + case mcc::MccCoordinateHAFmt: + case mcc::MccCoordinateAZFmt: + case mcc::MccCoordinateZDFmt: + case mcc::MccCoordinateALTFmt: + case mcc::MccCoordinateTMFmt: + case mcc::MccCoordinatePKFmt: + fmt_order.push_back(*it); + do_fmt = false; + break; + default: + throw std::format_error("Invalid format argument for celestial point"); + } + } + } + + template + FmtContext::iterator format(mcc::mcc_celestial_point_c auto cp, FmtContext& ctx) const + { + std::ostringstream out; + + if (fmt_order.empty()) { + return ctx.out(); + } + + for (auto& el : fmt_order) { + } + + return std::ranges::copy(std::move(out).str(), ctx.out()).out; + } +}; diff --git a/mcc/mcc_netserver_proto.h b/mcc/mcc_netserver_proto.h index b35a610..a6c4203 100644 --- a/mcc/mcc_netserver_proto.h +++ b/mcc/mcc_netserver_proto.h @@ -682,7 +682,7 @@ protected: (*this)(value.count(), bytes); } else if constexpr (mcc_eqt_hrz_coord_c) { // output format: RA, DEC, HA, AZ, ZD, ALT, X, Y, pair-kind, time-point - // in the case of sexagesimal output X,Y coordinates will be interprateted + // in the case of sexagesimal output X,Y coordinates will be interpretated // according to value.pair_kind field if (_currentCoordFormat == MccNetMessageCoordFormat::CFMT_DEGREES) { std::format_to(std::back_inserter(bytes), "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",