Complete Examples

Full working examples demonstrating LayKit features.

Basic GDSII File Creation

Complete program to create a GDSII file with multiple elements:

use laykit::{Boundary, GDSElement, GDSIIFile, GDSStructure, GDSTime, GPath, GText};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create library
    let mut gds = GDSIIFile::new("DEMO_LIB".to_string());
    gds.units = (1e-6, 1e-9); // 1µm, 1nm
    
    // Create structure
    let mut structure = GDSStructure {
        name: "TOP_CELL".to_string(),
        creation_time: GDSTime::now(),
        modification_time: GDSTime::now(),
        elements: Vec::new(),
    };
    
    // Add rectangle
    structure.elements.push(GDSElement::Boundary(Boundary {
        layer: 1,
        datatype: 0,
        xy: vec![
            (0, 0),
            (10000, 0),
            (10000, 5000),
            (0, 5000),
            (0, 0),
        ],
        properties: Vec::new(),
    }));
    
    // Add path
    structure.elements.push(GDSElement::Path(GPath {
        layer: 2,
        datatype: 0,
        pathtype: 0,
        width: Some(100),
        xy: vec![(0, 0), (5000, 0), (5000, 5000)],
        properties: Vec::new(),
    }));
    
    // Add text
    structure.elements.push(GDSElement::Text(GText {
        layer: 3,
        texttype: 0,
        string: "DEMO".to_string(),
        xy: (2500, 2500),
        strans: None,
        properties: Vec::new(),
    }));
    
    gds.structures.push(structure);
    gds.write_to_file("demo.gds")?;
    
    println!("✅ Created demo.gds");
    Ok(())
}

Format Conversion

Convert between GDSII and OASIS:

use laykit::{GDSIIFile, OASISFile, converter};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Read GDSII
    println!("Reading GDSII file...");
    let gds = GDSIIFile::read_from_file("input.gds")?;
    println!("  Library: {}", gds.library_name);
    println!("  Structures: {}", gds.structures.len());
    
    // Convert to OASIS
    println!("Converting to OASIS...");
    let oasis = converter::gdsii_to_oasis(&gds)?;
    oasis.write_to_file("output.oas")?;
    println!("  ✅ Written output.oas");
    
    // Read OASIS
    println!("Reading OASIS file...");
    let oasis = OASISFile::read_from_file("output.oas")?;
    println!("  Cells: {}", oasis.cells.len());
    
    // Convert back to GDSII
    println!("Converting to GDSII...");
    let gds2 = converter::oasis_to_gdsii(&oasis)?;
    gds2.write_to_file("roundtrip.gds")?;
    println!("  ✅ Written roundtrip.gds");
    
    println!("\n✅ All conversions completed!");
    Ok(())
}

Processing All Elements

Iterate through and analyze all elements:

use laykit::{GDSIIFile, GDSElement};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let gds = GDSIIFile::read_from_file("design.gds")?;
    
    let mut stats = Statistics::default();
    
    for structure in &gds.structures {
        println!("\n📦 Structure: {}", structure.name);
        
        for element in &structure.elements {
            stats.total_elements += 1;
            
            match element {
                GDSElement::Boundary(b) => {
                    stats.boundaries += 1;
                    println!("  ▢ Boundary: layer {}, {} vertices", 
                        b.layer, b.xy.len());
                }
                GDSElement::Path(p) => {
                    stats.paths += 1;
                    println!("  ─ Path: layer {}, width {:?}", 
                        p.layer, p.width);
                }
                GDSElement::Text(t) => {
                    stats.texts += 1;
                    println!("  T Text: \"{}\"", t.string);
                }
                GDSElement::StructRef(s) => {
                    stats.refs += 1;
                    println!("  → Reference: {}", s.sname);
                }
                GDSElement::ArrayRef(a) => {
                    stats.arrays += 1;
                    println!("  ⊞ Array: {} [{}×{}]", 
                        a.sname, a.columns, a.rows);
                }
                GDSElement::Node(n) => {
                    stats.nodes += 1;
                    println!("  ◉ Node: layer {}", n.layer);
                }
                GDSElement::Box(b) => {
                    stats.boxes += 1;
                    println!("  □ Box: layer {}", b.layer);
                }
            }
        }
    }
    
    println!("\n📊 Statistics:");
    println!("  Total elements: {}", stats.total_elements);
    println!("  Boundaries: {}", stats.boundaries);
    println!("  Paths: {}", stats.paths);
    println!("  Texts: {}", stats.texts);
    println!("  References: {}", stats.refs);
    println!("  Arrays: {}", stats.arrays);
    println!("  Nodes: {}", stats.nodes);
    println!("  Boxes: {}", stats.boxes);
    
    Ok(())
}

#[derive(Default)]
struct Statistics {
    total_elements: usize,
    boundaries: usize,
    paths: usize,
    texts: usize,
    refs: usize,
    arrays: usize,
    nodes: usize,
    boxes: usize,
}

Hierarchical Design

Create a design with cell references:

use laykit::{Boundary, GDSElement, GDSIIFile, GDSStructure, 
             GDSTime, StructRef};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut gds = GDSIIFile::new("HIERARCHICAL".to_string());
    gds.units = (1e-6, 1e-9);
    
    // Create subcell
    let mut subcell = GDSStructure {
        name: "SUBCELL".to_string(),
        creation_time: GDSTime::now(),
        modification_time: GDSTime::now(),
        elements: Vec::new(),
    };
    
    subcell.elements.push(GDSElement::Boundary(Boundary {
        layer: 1,
        datatype: 0,
        xy: vec![(0, 0), (1000, 0), (1000, 1000), (0, 1000), (0, 0)],
        properties: Vec::new(),
    }));
    
    // Create top cell
    let mut topcell = GDSStructure {
        name: "TOPCELL".to_string(),
        creation_time: GDSTime::now(),
        modification_time: GDSTime::now(),
        elements: Vec::new(),
    };
    
    // Add multiple instances of subcell
    for i in 0..3 {
        topcell.elements.push(GDSElement::StructRef(StructRef {
            sname: "SUBCELL".to_string(),
            xy: (i * 2000, 0),
            strans: None,
            properties: Vec::new(),
        }));
    }
    
    gds.structures.push(subcell);
    gds.structures.push(topcell);
    gds.write_to_file("hierarchical.gds")?;
    
    println!("✅ Created hierarchical.gds");
    Ok(())
}

Running Examples

The repository includes working examples:

# Clone repository
git clone https://github.com/giridharsalana/laykit.git
cd laykit

# Run basic usage example
cargo run --example basic_usage

# Run GDSII-only example
cargo run --example gdsii_only

# Run OASIS-only example
cargo run --example oasis_only