ifc_lite_landxml/alignment/
render_data.rs1use super::{LandXmlAlignmentDocument, LandXmlAlignmentRenderSpan};
8
9const POINTS_PER_SPAN: usize = 65;
10const MAX_POINTS: usize = 250_000;
11const MAX_REFUSALS: usize = 1_024;
12
13#[derive(Clone, Debug, serde::Deserialize, PartialEq, serde::Serialize)]
15pub struct LandXmlAlignmentRenderRefusal {
16 pub source_id: String,
17 pub message: String,
18}
19
20#[derive(Clone, Debug, PartialEq, serde::Serialize)]
23pub struct LandXmlAlignmentRenderData {
24 pub spans: Vec<LandXmlAlignmentRenderSpan>,
25 pub refusals: Vec<LandXmlAlignmentRenderRefusal>,
26 pub truncated: bool,
27}
28
29pub fn alignment_render_data(document: &LandXmlAlignmentDocument) -> LandXmlAlignmentRenderData {
32 let mut spans = Vec::new();
33 let mut refusals = Vec::new();
34 let mut point_count = 0usize;
35 let mut truncated = false;
36 for alignment in &document.alignments {
37 for segment in &alignment.segments {
38 match segment.render_span(POINTS_PER_SPAN) {
39 Ok(Some(span)) => {
40 let Some(next_point_count) = point_count.checked_add(span.points.len()) else {
41 return LandXmlAlignmentRenderData {
42 spans,
43 refusals,
44 truncated: true,
45 };
46 };
47 if next_point_count > MAX_POINTS {
48 return LandXmlAlignmentRenderData {
49 spans,
50 refusals,
51 truncated: true,
52 };
53 }
54 point_count = next_point_count;
55 spans.push(span);
56 }
57 Ok(None) => {}
58 Err(error) if refusals.len() < MAX_REFUSALS => {
59 refusals.push(LandXmlAlignmentRenderRefusal {
60 source_id: segment.source_id.0.clone(),
61 message: error.to_string(),
62 });
63 }
64 Err(_) => truncated = true,
65 }
66 }
67 }
68 LandXmlAlignmentRenderData {
69 spans,
70 refusals,
71 truncated,
72 }
73}