diff --git a/src/client.rs b/src/client.rs index 1e86c76..038c496 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1293,163 +1293,46 @@ fn pad_netlist_from_footprint_items( fn selection_item_detail(item: &prost_types::Any) -> Result { if item.type_url == envelope::type_url("kiapi.board.types.Track") { let track = decode_any::(item, "kiapi.board.types.Track")?; - let id = track.id.map_or_else(|| "-".to_string(), |id| id.value); - let start = track - .start - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let end = track - .end - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let width = track - .width - .map_or_else(|| "-".to_string(), |w| w.value_nm.to_string()); - let layer = layer_to_model(track.layer).name; - let net = track - .net - .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) - .unwrap_or_else(|| "-".to_string()); - - return Ok(format!( - "track id={id} start_nm={start} end_nm={end} width_nm={width} layer={layer} net={net}" - )); + return Ok(format_track_selection_detail(track)); } if item.type_url == envelope::type_url("kiapi.board.types.Arc") { let arc = decode_any::(item, "kiapi.board.types.Arc")?; - let id = arc.id.map_or_else(|| "-".to_string(), |id| id.value); - let start = arc - .start - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let mid = arc - .mid - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let end = arc - .end - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let width = arc - .width - .map_or_else(|| "-".to_string(), |w| w.value_nm.to_string()); - let layer = layer_to_model(arc.layer).name; - let net = arc - .net - .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!( - "arc id={id} start_nm={start} mid_nm={mid} end_nm={end} width_nm={width} layer={layer} net={net}" - )); + return Ok(format_arc_selection_detail(arc)); } if item.type_url == envelope::type_url("kiapi.board.types.Via") { let via = decode_any::(item, "kiapi.board.types.Via")?; - let id = via.id.map_or_else(|| "-".to_string(), |id| id.value); - let position = via - .position - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let net = via - .net - .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) - .unwrap_or_else(|| "-".to_string()); - let via_type = board_types::ViaType::try_from(via.r#type) - .map(|value| value.as_str_name().to_string()) - .unwrap_or_else(|_| format!("UNKNOWN({})", via.r#type)); - return Ok(format!( - "via id={id} pos_nm={position} type={via_type} net={net}" - )); + return Ok(format_via_selection_detail(via)); } if item.type_url == envelope::type_url("kiapi.board.types.FootprintInstance") { - let fp = decode_any::( + let footprint = decode_any::( item, "kiapi.board.types.FootprintInstance", )?; - let id = fp.id.map_or_else(|| "-".to_string(), |id| id.value); - let reference = fp - .reference_field - .as_ref() - .and_then(|field| field.text.as_ref()) - .and_then(|board_text| board_text.text.as_ref()) - .map(|text| text.text.clone()) - .unwrap_or_else(|| "-".to_string()); - let position = fp - .position - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let orientation_deg = fp.orientation.map_or_else( - || "-".to_string(), - |orientation| orientation.value_degrees.to_string(), - ); - let layer = layer_to_model(fp.layer).name; - let pad_count = fp - .definition - .as_ref() - .map(|definition| { - definition - .items - .iter() - .filter(|entry| entry.type_url == envelope::type_url("kiapi.board.types.Pad")) - .count() - }) - .unwrap_or(0); - return Ok(format!( - "footprint id={id} ref={reference} pos_nm={position} orientation_deg={orientation_deg} layer={layer} pad_count={pad_count}" - )); + return Ok(format_footprint_selection_detail(footprint)); } if item.type_url == envelope::type_url("kiapi.board.types.Field") { let field = decode_any::(item, "kiapi.board.types.Field")?; - let text = field - .text - .as_ref() - .and_then(|board_text| board_text.text.as_ref()) - .map(|text| text.text.clone()) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!( - "field name={} visible={} text={}", - field.name, field.visible, text - )); + return Ok(format_field_selection_detail(field)); } if item.type_url == envelope::type_url("kiapi.board.types.BoardText") { let text = decode_any::(item, "kiapi.board.types.BoardText")?; - let id = text.id.map_or_else(|| "-".to_string(), |id| id.value); - let layer = layer_to_model(text.layer).name; - let body = text - .text - .as_ref() - .map(|value| value.text.clone()) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!("text id={id} layer={layer} text={body}")); + return Ok(format_board_text_selection_detail(text)); } if item.type_url == envelope::type_url("kiapi.board.types.BoardTextBox") { let textbox = decode_any::(item, "kiapi.board.types.BoardTextBox")?; - let id = textbox.id.map_or_else(|| "-".to_string(), |id| id.value); - let layer = layer_to_model(textbox.layer).name; - let body = textbox - .textbox - .as_ref() - .map(|value| value.text.clone()) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!("textbox id={id} layer={layer} text={body}")); + return Ok(format_board_textbox_selection_detail(textbox)); } if item.type_url == envelope::type_url("kiapi.board.types.Pad") { let pad = decode_any::(item, "kiapi.board.types.Pad")?; - let id = pad.id.map_or_else(|| "-".to_string(), |id| id.value); - let pad_type = board_types::PadType::try_from(pad.r#type) - .map(|value| value.as_str_name().to_string()) - .unwrap_or_else(|_| format!("UNKNOWN({})", pad.r#type)); - let position = pad - .position - .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); - let net = pad - .net - .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!( - "pad id={id} number={} type={pad_type} pos_nm={position} net={net}", - pad.number - )); + return Ok(format_pad_selection_detail(pad)); } if item.type_url == envelope::type_url("kiapi.board.types.BoardGraphicShape") { @@ -1457,67 +1340,222 @@ fn selection_item_detail(item: &prost_types::Any) -> Result item, "kiapi.board.types.BoardGraphicShape", )?; - let id = shape.id.map_or_else(|| "-".to_string(), |id| id.value); - let layer = layer_to_model(shape.layer).name; - let net = shape - .net - .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) - .unwrap_or_else(|| "-".to_string()); - let geometry = shape - .shape - .as_ref() - .map(|graphic| format!("{:?}", graphic.geometry)) - .unwrap_or_else(|| "-".to_string()); - return Ok(format!( - "graphic id={id} layer={layer} net={net} geometry={geometry}" - )); + return Ok(format_board_graphic_shape_selection_detail(shape)); } if item.type_url == envelope::type_url("kiapi.board.types.Zone") { let zone = decode_any::(item, "kiapi.board.types.Zone")?; - let id = zone.id.map_or_else(|| "-".to_string(), |id| id.value); - let zone_type = board_types::ZoneType::try_from(zone.r#type) - .map(|value| value.as_str_name().to_string()) - .unwrap_or_else(|_| format!("UNKNOWN({})", zone.r#type)); - return Ok(format!( - "zone id={id} name={} type={} layer_count={} filled={} polygon_count={}", - zone.name, - zone_type, - zone.layers.len(), - zone.filled, - zone.filled_polygons.len() - )); + return Ok(format_zone_selection_detail(zone)); } if item.type_url == envelope::type_url("kiapi.board.types.Dimension") { let dimension = decode_any::(item, "kiapi.board.types.Dimension")?; - let id = dimension.id.map_or_else(|| "-".to_string(), |id| id.value); - let layer = layer_to_model(dimension.layer).name; - let text = dimension - .text - .as_ref() - .map(|value| value.text.clone()) - .unwrap_or_else(|| "-".to_string()); - let style = format!("{:?}", dimension.dimension_style); - return Ok(format!( - "dimension id={id} layer={layer} text={} style={style}", - text - )); + return Ok(format_dimension_selection_detail(dimension)); } if item.type_url == envelope::type_url("kiapi.board.types.Group") { let group = decode_any::(item, "kiapi.board.types.Group")?; - let id = group.id.map_or_else(|| "-".to_string(), |id| id.value); - return Ok(format!( - "group id={id} name={} item_count={}", - group.name, - group.items.len() - )); + return Ok(format_group_selection_detail(group)); } Ok(format!("unparsed payload ({} bytes)", item.value.len())) } +fn format_track_selection_detail(track: board_types::Track) -> String { + let id = track.id.map_or_else(|| "-".to_string(), |id| id.value); + let start = track + .start + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let end = track + .end + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let width = track + .width + .map_or_else(|| "-".to_string(), |w| w.value_nm.to_string()); + let layer = layer_to_model(track.layer).name; + let net = track + .net + .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) + .unwrap_or_else(|| "-".to_string()); + format!("track id={id} start_nm={start} end_nm={end} width_nm={width} layer={layer} net={net}") +} + +fn format_arc_selection_detail(arc: board_types::Arc) -> String { + let id = arc.id.map_or_else(|| "-".to_string(), |id| id.value); + let start = arc + .start + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let mid = arc + .mid + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let end = arc + .end + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let width = arc + .width + .map_or_else(|| "-".to_string(), |w| w.value_nm.to_string()); + let layer = layer_to_model(arc.layer).name; + let net = arc + .net + .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) + .unwrap_or_else(|| "-".to_string()); + format!( + "arc id={id} start_nm={start} mid_nm={mid} end_nm={end} width_nm={width} layer={layer} net={net}" + ) +} + +fn format_via_selection_detail(via: board_types::Via) -> String { + let id = via.id.map_or_else(|| "-".to_string(), |id| id.value); + let position = via + .position + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let net = via + .net + .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) + .unwrap_or_else(|| "-".to_string()); + let via_type = board_types::ViaType::try_from(via.r#type) + .map(|value| value.as_str_name().to_string()) + .unwrap_or_else(|_| format!("UNKNOWN({})", via.r#type)); + format!("via id={id} pos_nm={position} type={via_type} net={net}") +} + +fn format_footprint_selection_detail(footprint: board_types::FootprintInstance) -> String { + let id = footprint.id.map_or_else(|| "-".to_string(), |id| id.value); + let reference = footprint + .reference_field + .as_ref() + .and_then(|field| field.text.as_ref()) + .and_then(|board_text| board_text.text.as_ref()) + .map(|text| text.text.clone()) + .unwrap_or_else(|| "-".to_string()); + let position = footprint + .position + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let orientation_deg = footprint.orientation.map_or_else( + || "-".to_string(), + |orientation| orientation.value_degrees.to_string(), + ); + let layer = layer_to_model(footprint.layer).name; + let pad_count = footprint + .definition + .as_ref() + .map(|definition| { + definition + .items + .iter() + .filter(|entry| entry.type_url == envelope::type_url("kiapi.board.types.Pad")) + .count() + }) + .unwrap_or(0); + format!( + "footprint id={id} ref={reference} pos_nm={position} orientation_deg={orientation_deg} layer={layer} pad_count={pad_count}" + ) +} + +fn format_field_selection_detail(field: board_types::Field) -> String { + let text = field + .text + .as_ref() + .and_then(|board_text| board_text.text.as_ref()) + .map(|text| text.text.clone()) + .unwrap_or_else(|| "-".to_string()); + format!( + "field name={} visible={} text={}", + field.name, field.visible, text + ) +} + +fn format_board_text_selection_detail(text: board_types::BoardText) -> String { + let id = text.id.map_or_else(|| "-".to_string(), |id| id.value); + let layer = layer_to_model(text.layer).name; + let body = text + .text + .as_ref() + .map(|value| value.text.clone()) + .unwrap_or_else(|| "-".to_string()); + format!("text id={id} layer={layer} text={body}") +} + +fn format_board_textbox_selection_detail(textbox: board_types::BoardTextBox) -> String { + let id = textbox.id.map_or_else(|| "-".to_string(), |id| id.value); + let layer = layer_to_model(textbox.layer).name; + let body = textbox + .textbox + .as_ref() + .map(|value| value.text.clone()) + .unwrap_or_else(|| "-".to_string()); + format!("textbox id={id} layer={layer} text={body}") +} + +fn format_pad_selection_detail(pad: board_types::Pad) -> String { + let id = pad.id.map_or_else(|| "-".to_string(), |id| id.value); + let pad_type = board_types::PadType::try_from(pad.r#type) + .map(|value| value.as_str_name().to_string()) + .unwrap_or_else(|_| format!("UNKNOWN({})", pad.r#type)); + let position = pad + .position + .map_or_else(|| "-".to_string(), |v| format!("{},{}", v.x_nm, v.y_nm)); + let net = pad + .net + .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) + .unwrap_or_else(|| "-".to_string()); + format!( + "pad id={id} number={} type={pad_type} pos_nm={position} net={net}", + pad.number + ) +} + +fn format_board_graphic_shape_selection_detail(shape: board_types::BoardGraphicShape) -> String { + let id = shape.id.map_or_else(|| "-".to_string(), |id| id.value); + let layer = layer_to_model(shape.layer).name; + let net = shape + .net + .map(|n| format!("{}:{}", n.code.map_or(0, |c| c.value), n.name)) + .unwrap_or_else(|| "-".to_string()); + let geometry = shape + .shape + .as_ref() + .map(|graphic| format!("{:?}", graphic.geometry)) + .unwrap_or_else(|| "-".to_string()); + format!("graphic id={id} layer={layer} net={net} geometry={geometry}") +} + +fn format_zone_selection_detail(zone: board_types::Zone) -> String { + let id = zone.id.map_or_else(|| "-".to_string(), |id| id.value); + let zone_type = board_types::ZoneType::try_from(zone.r#type) + .map(|value| value.as_str_name().to_string()) + .unwrap_or_else(|_| format!("UNKNOWN({})", zone.r#type)); + format!( + "zone id={id} name={} type={} layer_count={} filled={} polygon_count={}", + zone.name, + zone_type, + zone.layers.len(), + zone.filled, + zone.filled_polygons.len() + ) +} + +fn format_dimension_selection_detail(dimension: board_types::Dimension) -> String { + let id = dimension.id.map_or_else(|| "-".to_string(), |id| id.value); + let layer = layer_to_model(dimension.layer).name; + let text = dimension + .text + .as_ref() + .map(|value| value.text.clone()) + .unwrap_or_else(|| "-".to_string()); + let style = format!("{:?}", dimension.dimension_style); + format!("dimension id={id} layer={layer} text={} style={style}", text) +} + +fn format_group_selection_detail(group: board_types::Group) -> String { + let id = group.id.map_or_else(|| "-".to_string(), |id| id.value); + format!( + "group id={id} name={} item_count={}", + group.name, + group.items.len() + ) +} + fn any_to_pretty_debug(item: &prost_types::Any) -> Result { if item.type_url == envelope::type_url("kiapi.board.types.Track") { let value = decode_any::(item, "kiapi.board.types.Track")?;