Skip to main content

xisf_header/
property.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! The [`Property`] record for XISF `<Property>` elements.
6
7/// A single XISF `<Property>`: its `type`, value text, and the optional
8/// `comment` and `format` attributes, all kept verbatim.
9///
10/// Unlike FITS keywords, XISF property values are *not* FITS-formatted: they
11/// are stored raw, without any quote layer.
12///
13/// A parsed value round-trips unchanged, but its serialized *shape* may not: a
14/// `String` property written as long-form child text (`<Property
15/// id=…>text</Property>`) is re-emitted in `value=` attribute form. The parsed
16/// value is identical, so [`Header`](crate::Header) equality still holds.
17///
18/// ```
19/// use xisf_header::Property;
20///
21/// let p = Property::new("String", "NGC 7000");
22/// assert_eq!(p.type_, "String");
23/// assert_eq!(p.value, "NGC 7000");
24/// assert_eq!(p.comment, "");
25/// ```
26#[derive(Debug, Clone, PartialEq, Eq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct Property {
29    /// The XISF `type` attribute (e.g. `String`, `Float32`, `TimePoint`),
30    /// kept verbatim.
31    #[cfg_attr(feature = "serde", serde(rename = "type"))]
32    pub type_: String,
33    /// The raw value text. Read from the `value` attribute, or from the
34    /// element's child text for the long `String` form; writes always emit it
35    /// as a `value` attribute.
36    pub value: String,
37    /// The `comment` attribute (empty when absent).
38    pub comment: String,
39    /// The `format` attribute (empty when absent).
40    pub format: String,
41}
42
43impl Default for Property {
44    fn default() -> Self {
45        Self {
46            type_: "String".to_owned(),
47            value: String::new(),
48            comment: String::new(),
49            format: String::new(),
50        }
51    }
52}
53
54impl Property {
55    /// Create a property of the given XISF type with a raw value.
56    ///
57    /// ```
58    /// use xisf_header::Property;
59    /// let p = Property::new("Float32", "0.135");
60    /// assert_eq!(p.type_, "Float32");
61    /// assert_eq!(p.value, "0.135");
62    /// ```
63    pub fn new(type_: impl Into<String>, value: impl Into<String>) -> Self {
64        Self {
65            type_: type_.into(),
66            value: value.into(),
67            ..Self::default()
68        }
69    }
70}