bacnet-objects 0.13.0

BACnet object model: traits, database, and standard object types
Documentation
//! Private property-resize authority.

use super::{common, file_full, FileObject};
use bacnet_types::enums::{FileAccessMethod, PropertyIdentifier};
use bacnet_types::error::Error;
use bacnet_types::primitives::PropertyValue;

pub(super) fn write_stream(file: &mut FileObject, value: PropertyValue) -> Result<(), Error> {
    if file.file_access_method != FileAccessMethod::STREAM_ACCESS.to_raw() || file.read_only {
        return Err(common::write_access_denied_error());
    }
    let PropertyValue::Unsigned(target) = value else {
        return Err(common::invalid_data_type_error());
    };
    let current = file.data.len() as u64;
    if target == current {
        return Ok(());
    }
    if target > file.max_file_size.max(current) {
        return Err(file_full());
    }
    let target = usize::try_from(target).map_err(|_| file_full())?;
    let mut updated = file.data.clone();
    updated.resize(target, 0);
    file.set_data(updated);
    Ok(())
}

pub(super) fn write_records(file: &mut FileObject, value: PropertyValue) -> Result<(), Error> {
    if file.file_access_method != FileAccessMethod::RECORD_ACCESS.to_raw() || file.read_only {
        return Err(common::write_access_denied_error());
    }
    let PropertyValue::Unsigned(target) = value else {
        return Err(common::invalid_data_type_error());
    };
    let current = file.records.len() as u64;
    if target == current {
        return Ok(());
    }
    if target > file.max_record_count.max(current) {
        return Err(file_full());
    }
    let target = usize::try_from(target).map_err(|_| file_full())?;
    let mut updated = file.records.clone();
    updated.resize(target, Vec::new());
    file.set_records(updated);
    Ok(())
}

pub(super) fn is_writable(file: &FileObject, property: PropertyIdentifier) -> bool {
    matches!(
        property,
        PropertyIdentifier::DESCRIPTION
            | PropertyIdentifier::ARCHIVE
            | PropertyIdentifier::FILE_TYPE
    ) || (property == PropertyIdentifier::FILE_SIZE
        && file.file_access_method == FileAccessMethod::STREAM_ACCESS.to_raw()
        && !file.read_only)
        || (property == PropertyIdentifier::RECORD_COUNT
            && file.file_access_method == FileAccessMethod::RECORD_ACCESS.to_raw()
            && !file.read_only)
}