Core Traits and Registration
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
The lc_plugin crate root defines the plugin contracts that LinkCAD calls through the native plugin ABI. Implement FormatDescriptor on every format type, then implement Reader, Writer, or both depending on whether the plugin imports files, exports files, or supports a round trip.
Most plugins can import the common surface from lc_plugin::prelude::*. Larger plugins often use explicit module imports so it is clear which code creates geometry, enumerates geometry, logs diagnostics, and reads options.
Python plugins use the same concepts through linkcad.v1.plugin: FormatReader, FormatWriter, DrawingBuilder, WriterController, DialogSpec, and the shared format enums.
Key Public Items
| Item | Purpose |
|---|---|
FormatDescriptor | Describes format capabilities to the host. Implemented by readers and writers. |
Reader | Import plugin trait. Parses source files into a LinkCAD drawing. |
Writer | Export plugin trait. Writes LinkCAD drawing data to a target file. |
EndCap | End-cap style for polylines and arcs. |
FillRule | Polygon fill-rule policy passed to writer callbacks. |
Phase | Reader post-processing phase. |
LayerFlags | Layer-addressing policy for imported entities. |
register_reader! | Registers an import-only plugin and exports GetPlugIn. |
register_writer! | Registers an export-only plugin and exports GetPlugIn. |
register_format! | Registers a combined import/export plugin and exports GetPlugIn. |
prelude | Re-exports common plugin traits, wrappers, entities, enums, and lc_types. |
FormatDescriptor
pub trait FormatDescriptor { fn describe_format(&self, fmt: &mut Format);}Use describe_format() to set static format capabilities before an import or export starts. Typical calls include Format::set_attributes(), Format::set_file_name_extension(), and layer/cell validation constraints. See format for the full descriptor API.
Reader
pub trait Reader: FormatDescriptor { fn parse_file( &mut self, path: &str, builder: &mut DrawingBuilder, file_size: i64, current_file: i32, file_count: i32, ) -> bool;
fn post_process( &mut self, phase: Phase, drawing: &mut Drawing, progress: Option<&mut DrawingBuilder>, log: &mut EventLog, resolution: &Resolution, ) -> bool;}parse_file() is required. Return true when the source file was parsed successfully and false when LinkCAD should treat the import as failed. Use DrawingBuilder to create cells, layers, shapes, text, and references.
post_process() is optional and defaults to true. Override it to run drawing-level helpers after parsing, such as deferred polarity merging or layer boolean operations. See drawing.
Writer
pub trait Writer: FormatDescriptor { fn write_file(&mut self, path: &str, ctrl: &mut WriterController) -> bool;
fn write_polygon(&mut self, poly: &Polygon, fill_rule: FillRule) -> bool; fn write_polyline(&mut self, pline: &Polyline) -> bool; fn write_arc(&mut self, arc: &Arc) -> bool; fn write_nurbs(&mut self, nurbs: &Nurbs) -> bool; fn write_ellipse(&mut self, ellipse: &Ellipse) -> bool; fn write_donut(&mut self, donut: &Donut) -> bool; fn write_text(&mut self, text: &Text) -> bool; fn write_ref(&mut self, r: &Ref, layer: &Layer) -> bool;}write_file() is required. Use WriterController to enumerate layers, cells, fonts, transformations, and rendered geometry.
The entity callbacks default to false. Override the callbacks that match the geometry your format exports when you use WriterController::render_cell() or WriterController::render_cell_in_layer_order().
Enums
EndCap
pub enum EndCap { Round = 0, SquareExtended = 1, SquareFlat = 2,}Used by DrawingBuilder::create_polyline() and DrawingBuilder::create_arc().
FillRule
pub enum FillRule { NonZero = 0, EvenOdd = 1,}Passed to Writer::write_polygon() and returned by WriterController::fill_rule().
Phase
pub enum Phase { ParsedFile = 0, ParsedAll = 1, ClosedOpenCells = 2, ResolvedRefs = 3, SelectedMainCell = 4, ResolvedLayersByBlock = 5, AutoNumberedZ = 6,}Identifies the host post-processing phase for Reader::post_process().
LayerFlags
pub enum LayerFlags { Normal = 0, ByLayer = 1, ByBlock = 2,}Passed to DrawingBuilder::set_entity_layer_style() to control how imported entity layer information is interpreted.
Registration Macros
Registration macros generate the native GetPlugIn entry point and perform the host plugin API major-version check before creating the plugin handle.
register_reader!
lc_plugin::register_reader! { name: "Example Reader", extensions: "*.exa", license: 0, create: || Box::new(ExampleReader::default()),}Optional fields are plugin_name and description.
register_writer!
lc_plugin::register_writer! { name: "Example Writer", extensions: "*.exa", license: 0, create: || Box::new(ExampleWriter::default()),}Optional fields are plugin_name and description.
register_format!
lc_plugin::register_format! { name: "Example Format", extensions: "*.exa", license: 0, reader: || Box::new(ExampleReader::default()), writer: || Box::new(ExampleWriter::default()),}register_format! also supports import/export dialog specs and a source inspector:
lc_plugin::register_format! { name: "Example Format", extensions: "*.exa", license: 0, plugin_name: "Example Plugin", description: "Example native Rust plugin", reader: || Box::new(ExampleReader::default()), writer: || Box::new(ExampleWriter::default()), import_dialog: import_dialog_spec(), export_dialog: export_dialog_spec(), source_inspector: || Box::new(ExampleInspector),}Dialog registration automatically calls DialogSpec::register_options() before the host receives the dialog JSON. See dialog, options, and inspect.
Minimal Import Shape
use lc_plugin::prelude::*;
#[derive(Default)]struct ExampleReader;
impl FormatDescriptor for ExampleReader { fn describe_format(&self, fmt: &mut Format) { fmt.set_attributes(FormatAttributes::LAYER_NAMES | FormatAttributes::CELL_NAMES); fmt.set_file_name_extension("exa"); }}
impl Reader for ExampleReader { fn parse_file( &mut self, _path: &str, builder: &mut DrawingBuilder, _file_size: i64, _current_file: i32, _file_count: i32, ) -> bool { builder.open_cell_by_name("TOP", true, false); builder.select_layer_by_name("L1"); builder.create_rectangle(Point::new(0, 0), Point::new(1000, 1000)); builder.close_cell(); true }}Error Handling
Plugin callbacks cross a host boundary. Return false for recoverable failures and log diagnostics through EventLog or the controller-specific log() accessors. The Rust wrappers avoid panicking paths; plugin code should also keep errors explicit at the callback boundary.