use der::{Decode, Encode, Reader, Writer};
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "python")]
use pyo3::exceptions::PyValueError;
#[cfg(feature = "python")]
use pyo3::prelude::*;
#[cfg(feature = "python")]
use pyo3::types::{PyBytes, PyType};
#[cfg_attr(feature = "python", pyclass(get_all, set_all, module = "anise.astro"))]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DragData {
pub area_m2: f64,
pub coeff_drag: f64,
}
impl DragData {
pub fn from_area(area_m2: f64) -> Self {
Self {
area_m2,
..Default::default()
}
}
}
#[cfg(feature = "python")]
#[cfg_attr(feature = "python", pymethods)]
impl DragData {
#[new]
#[pyo3(signature = (area_m2, coeff_drag = None))]
fn py_new(area_m2: f64, coeff_drag: Option<f64>) -> Self {
Self {
area_m2,
coeff_drag: coeff_drag.unwrap_or(Self::default().coeff_drag),
}
}
fn __str__(&self) -> String {
format!("{self:?}")
}
fn __repr__(&self) -> String {
format!("{self:?} @ {self:p}")
}
#[classmethod]
pub fn from_asn1(_cls: &Bound<'_, PyType>, data: &[u8]) -> PyResult<Self> {
match Self::from_der(data) {
Ok(obj) => Ok(obj),
Err(e) => Err(PyValueError::new_err(format!("ASN.1 decoding error: {e}"))),
}
}
pub fn to_asn1<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
let mut buf = Vec::new();
match self.encode_to_vec(&mut buf) {
Ok(_) => Ok(PyBytes::new(py, &buf)),
Err(e) => Err(PyValueError::new_err(format!("ASN.1 encoding error: {e}"))),
}
}
}
impl Default for DragData {
fn default() -> Self {
Self {
area_m2: 0.0,
coeff_drag: 2.2,
}
}
}
impl Encode for DragData {
fn encoded_len(&self) -> der::Result<der::Length> {
self.area_m2.encoded_len()? + self.coeff_drag.encoded_len()?
}
fn encode(&self, encoder: &mut impl Writer) -> der::Result<()> {
self.area_m2.encode(encoder)?;
self.coeff_drag.encode(encoder)
}
}
impl<'a> Decode<'a> for DragData {
fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
Ok(Self {
area_m2: decoder.decode()?,
coeff_drag: decoder.decode()?,
})
}
}
#[cfg(test)]
mod drag_ut {
use super::{Decode, DragData, Encode};
#[test]
fn zero_repr() {
let repr = DragData {
area_m2: Default::default(),
coeff_drag: Default::default(),
};
let mut buf = vec![];
repr.encode_to_vec(&mut buf).unwrap();
let repr_dec = DragData::from_der(&buf).unwrap();
assert_eq!(repr, repr_dec);
}
#[test]
fn default_repr() {
let repr = DragData::default();
let mut buf = vec![];
repr.encode_to_vec(&mut buf).unwrap();
let repr_dec = DragData::from_der(&buf).unwrap();
assert_eq!(repr, repr_dec);
}
}