use super::TableEntry;
use crate::types::Handle;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BlockFlags {
pub anonymous: bool,
pub has_attributes: bool,
pub is_xref: bool,
pub is_xref_overlay: bool,
pub is_external: bool,
}
impl BlockFlags {
pub fn new() -> Self {
BlockFlags {
anonymous: false,
has_attributes: false,
is_xref: false,
is_xref_overlay: false,
is_external: false,
}
}
}
impl Default for BlockFlags {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BlockRecord {
pub handle: Handle,
pub block_entity_handle: Handle,
pub block_end_handle: Handle,
pub name: String,
pub flags: BlockFlags,
pub layout: Handle,
pub units: i16,
pub explodable: bool,
pub scale_uniformly: bool,
pub entity_handles: Vec<Handle>,
pub xref_path: String,
pub description: String,
pub insert_count_bytes: Vec<u8>,
pub preview_data: Vec<u8>,
pub insert_handles: Vec<Handle>,
}
impl BlockRecord {
pub fn new(name: impl Into<String>) -> Self {
BlockRecord {
handle: Handle::NULL,
block_entity_handle: Handle::NULL,
block_end_handle: Handle::NULL,
name: name.into(),
flags: BlockFlags::new(),
layout: Handle::NULL,
units: 0,
explodable: true,
scale_uniformly: false,
entity_handles: Vec::new(),
xref_path: String::new(),
description: String::new(),
insert_count_bytes: Vec::new(),
preview_data: Vec::new(),
insert_handles: Vec::new(),
}
}
pub fn model_space() -> Self {
BlockRecord {
handle: Handle::NULL,
block_entity_handle: Handle::NULL,
block_end_handle: Handle::NULL,
name: "*Model_Space".to_string(),
flags: BlockFlags::new(),
layout: Handle::NULL,
units: 0,
explodable: true,
scale_uniformly: false,
entity_handles: Vec::new(),
xref_path: String::new(),
description: String::new(),
insert_count_bytes: Vec::new(),
preview_data: Vec::new(),
insert_handles: Vec::new(),
}
}
pub fn paper_space() -> Self {
BlockRecord {
handle: Handle::NULL,
block_entity_handle: Handle::NULL,
block_end_handle: Handle::NULL,
name: "*Paper_Space".to_string(),
flags: BlockFlags::new(),
layout: Handle::NULL,
units: 0,
explodable: true,
scale_uniformly: false,
entity_handles: Vec::new(),
xref_path: String::new(),
description: String::new(),
insert_count_bytes: Vec::new(),
preview_data: Vec::new(),
insert_handles: Vec::new(),
}
}
pub fn is_model_space(&self) -> bool {
self.name == "*Model_Space"
}
pub fn is_paper_space(&self) -> bool {
self.name.starts_with("*Paper_Space")
}
pub fn is_layout(&self) -> bool {
!self.layout.is_null()
}
pub fn is_anonymous(&self) -> bool {
self.flags.anonymous || self.name.starts_with('*')
}
}
impl TableEntry for BlockRecord {
fn handle(&self) -> Handle {
self.handle
}
fn set_handle(&mut self, handle: Handle) {
self.handle = handle;
}
fn name(&self) -> &str {
&self.name
}
fn set_name(&mut self, name: String) {
self.name = name;
}
fn is_standard(&self) -> bool {
self.is_model_space() || self.is_paper_space()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_block_record_creation() {
let block = BlockRecord::new("MyBlock");
assert_eq!(block.name, "MyBlock");
assert!(block.explodable);
}
#[test]
fn test_model_space() {
let block = BlockRecord::model_space();
assert!(block.is_model_space());
assert!(block.is_standard());
assert!(!block.is_paper_space());
}
#[test]
fn test_paper_space() {
let block = BlockRecord::paper_space();
assert!(block.is_paper_space());
assert!(block.is_standard());
assert!(!block.is_model_space());
}
}