castep_cell_parser/pest_parser/
block.rs1use std::fmt::Display;
2
3use derive_builder::Builder;
4use pest::iterators::Pair;
5
6use crate::CellParseError;
7
8use super::Rule;
9
10#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Builder)]
12#[builder()]
13pub struct Block {
14 order: usize,
15 name: String,
16 values: Vec<String>,
17}
18
19impl Block {
20 pub fn new(order: usize, name: String, values: Vec<String>) -> Self {
21 Self {
22 order,
23 name,
24 values,
25 }
26 }
27
28 pub fn order(&self) -> usize {
29 self.order
30 }
31
32 pub fn name(&self) -> &str {
33 &self.name
34 }
35
36 pub fn values(&self) -> &[String] {
37 &self.values
38 }
39
40 pub fn values_mut(&mut self) -> &mut Vec<String> {
41 &mut self.values
42 }
43
44 pub fn from_pair(pair: Pair<'_, Rule>, order: usize) -> Self {
45 let inner_rules = pair.into_inner();
46 let block_name = inner_rules
47 .find_first_tagged("block_name")
48 .unwrap()
49 .as_str();
50 let block_lines = inner_rules
51 .find_tagged("block_values") .flat_map(|lines| {
53 lines
54 .into_inner()
55 .map(|pair| pair.as_str().to_string())
56 .collect::<Vec<String>>()
57 })
58 .collect::<Vec<String>>();
59 Self::new(order, block_name.to_string(), block_lines)
60 }
61}
62
63impl Display for Block {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 write!(
66 f,
67 "{}",
68 [
69 format!("%BLOCK {}", self.name()),
70 self.values()
71 .iter()
72 .map(|line| format!(" {line}"))
73 .collect::<Vec<String>>()
74 .join("\n"),
75 format!("%ENDBLOCK {}", self.name())
76 ]
77 .into_iter()
78 .filter(|line| !line.is_empty())
79 .collect::<Vec<String>>()
80 .join("\n")
81 )
82 }
83}
84
85pub trait BlockIO {
89 type Item;
90 fn from_block(block: &Block) -> Result<Self::Item, CellParseError>;
91 fn to_block(&self, order: usize) -> Block;
92}