rateslib/curves/interpolation/
intp_null.rs

1use crate::curves::nodes::NodesTimestamp;
2use crate::curves::CurveInterpolation;
3use crate::dual::Number;
4use bincode::config::legacy;
5use bincode::serde::{decode_from_slice, encode_to_vec};
6use chrono::NaiveDateTime;
7use pyo3::prelude::*;
8use pyo3::types::{PyBytes, PyTuple};
9use pyo3::{pyclass, pymethods, Bound, PyResult, Python};
10use serde::{Deserialize, Serialize};
11use std::cmp::PartialEq;
12
13/// Define a null interpolation object.
14///
15/// This is used by PyO3 binding to indicate interpolation occurs in Python.
16#[pyclass(module = "rateslib.rs")]
17#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
18pub struct NullInterpolator {}
19
20#[pymethods]
21impl NullInterpolator {
22    #[new]
23    pub fn new() -> Self {
24        NullInterpolator {}
25    }
26
27    // Pickling
28    pub fn __setstate__(&mut self, state: Bound<'_, PyBytes>) -> PyResult<()> {
29        *self = decode_from_slice(state.as_bytes(), legacy()).unwrap().0;
30        Ok(())
31    }
32    pub fn __getstate__<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
33        Ok(PyBytes::new(py, &encode_to_vec(&self, legacy()).unwrap()))
34    }
35    pub fn __getnewargs__<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyTuple>> {
36        Ok(PyTuple::empty(py))
37    }
38}
39
40impl CurveInterpolation for NullInterpolator {
41    fn interpolated_value(&self, _nodes: &NodesTimestamp, _date: &NaiveDateTime) -> Number {
42        panic!("NullInterpolator cannot be used to obtain interpolated values.");
43        #[allow(unreachable_code)]
44        Number::F64(0.0)
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use crate::curves::nodes::Nodes;
52    use crate::scheduling::ndt;
53    use indexmap::IndexMap;
54
55    fn nodes_timestamp_fixture() -> NodesTimestamp {
56        let nodes = Nodes::F64(IndexMap::from_iter(vec![
57            (ndt(2000, 1, 1), 1.0_f64),
58            (ndt(2001, 1, 1), 0.99_f64),
59            (ndt(2002, 1, 1), 0.98_f64),
60        ]));
61        NodesTimestamp::from(nodes)
62    }
63
64    #[test]
65    #[should_panic]
66    fn test_null_interpolation() {
67        let nts = nodes_timestamp_fixture();
68        let li = NullInterpolator::new();
69        li.interpolated_value(&nts, &ndt(2000, 7, 1));
70    }
71}