Giter Site home page Giter Site logo

dbrgn / gerber-types-rs Goto Github PK

View Code? Open in Web Editor NEW
14.0 5.0 3.0 178 KB

Gerber X2 (compatible with Gerber RS-274X) code-generating library for Rust. Not yet complete, breaking changes possible. Contributions welcome!

License: Apache License 2.0

Rust 100.00%
gerber pcb cam rust gerber-x2

gerber-types-rs's Introduction

Rust Gerber Library

Build status Crates.io

This crate implements the basic building blocks of Gerber X2 (compatible with Gerber RS-274X) code. It focusses on the low level types (to be used like an AST) and code generation and does not do any semantic checking.

For example, you can use an aperture without defining it. This will generate syntactically valid but semantially invalid Gerber code, but this module won't complain.

The plan is to write a high-level wrapper library on top of this. Early drafts are in progress but the design isn't fixed yet.

Current Gerber X2 spec: https://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf

Example

You can find an example in the examples directory. It's still quite verbose, the goal is to make the API a bit more ergonomic in the future. (This library has a low-level focus though, so it will never get a high-level API. That is the task of other libraries.)

To generate Gerber code for that example:

$ cargo run --example polarities-apertures

License

Licensed under either of

at your option.

gerber-types-rs's People

Contributors

connorkuehl avatar dbrgn avatar nemoandrea avatar twitchyliquid64 avatar ubruhin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gerber-types-rs's Issues

Add error checking for other serializable objects

MoirePrimitive and PolygonPrimitive enforce their invariants when they're being serialized.

Like this:

impl<W: Write> PartialGerberCode<W> for PolygonPrimitive {
    fn serialize_partial(&self, writer: &mut W) -> GerberResult<()> {
        // Vertice count invariants
        if self.vertices < 3 {
            return Err(GerberError::MissingDataError("There must be at least 3 vertices in a polygon".into()));
        }
        if self.vertices > 12 {
            return Err(GerberError::RangeError("The maximum number of vertices in a polygon is 12".into()));
        }
        if self.diameter.is_negative() {
            return Err(GerberError::RangeError("The diameter must not be negative".into()));
        }

Other types (like VectorLinePrimitive, etc.) should do this too ๐Ÿ˜ƒ

Enums vs Traits?

Some types like FileAttribute might be better implemented as a trait.

It would get rid of some of the nesting.

Support arithmetic in macro primitives

Most values in macro primitives can be calculated using arithmetic expressions.

The easiest way to do this would probably be to add an Expression(String) option to the MacroDecimal enum.

More memory efficient GerberCode trait

Right now the GerberCode trait allocates lots and lots of strings because it returns the String type. We should change this to using a writer object, similar to the way Display does it.

I already wondered whether we should actually use the Display implementation instead of using our own trait, but I don't think that's a good idea.

Handle type restrictions

The Gerber spec specifies a list of data types:

  • Integers
  • Decimals
  • Coordinate Numbers
  • Hexadecimal
  • Names
  • Strings

We should make sure that only valid values accrding to the spec can be passed in to types expecting these basic data types.

This means that we probably won't get around creating custom wrapper types.

Is there a way to create range types in Rust, e.g. a 32 bit signed integer >= 1? Or strings that only accept certain unicode codepoints? Ideally as much as possible at compile time.

@rnestler @dns2utf8

Meaning of GerberCode trait

Right now it's possible to use some types that implement the GerberCode trait and to generate code that is not a valid Gerber code line (because it's incomplete). Example:

FileAttribute::Part(Part::Single).to_code(...)

This will generate Part,Single which is not a valid line because it needs to be wrapped inside an ExtendedCode.

The question is whether incomplete and complete lines should be handled differently. For some of the types (especially plain enums) a simple Display implementation might be sufficient.

Higher Level API

Some brainstorming about a higher level API. What do we need for PCB creation?

The best approach would probably to have a context object, and then to add helper methods on top of that (builder style).

Some ideas:

use gerber::Layer;
use gerber::{FileAttribute, Part, FileFunction, ExtendedPosition, CopperType};
use gerber::{Aperture, Circle, Rectangular};

let mut layer = Layer::new();

// Set properties
layer.set_file_attribute(Part::Single);
layer.set_file_attribute(FileFunction(FileFunction::Copper {
    layer: 0,
    pos: ExtendedPosition::Top,
    copper_type: Some(CopperType::Signal),
}));

// Create apertures for traces
let trace_power = layer.create_aperture(Aperture::Circle(Circle::new(1.0)));

// Create apertures for pads
let pad_round = layer.create_aperture(Aperture::Circle(Circle::with_hole(1.2, 0.8)));
let pad_square = layer.create_aperture(Aperture::Rectangle(Rectangular::with_hole(1.2, 1.2, 0.8)));

// Flash pads
layer.flash((10.0, 10.0), pad_round);
layer.flash((20.0, 10.0), pad_round);
layer.flash((30.0, 10.0), pad_square);

// Draw trace connecting all pads
layer.draw_line((10.0, 10.0), (30.0, 10.0), trace_power);

TODO: Continue this brainstorming :)

cc @rnestler @ubruhin

Change struct constructors to use "Self" and update project's minimum required Rust version

Discussed in #22:

Change constructors to use the Self keyword when creating the new object like this:

impl Circle {
    pub fn new(diameter: f64) -> Self {
        Circle {
            diameter: diameter,
            hole_diameter: None,
        }
    }

To something like this:

impl Circle {
    pub fn new(diameter: f64) -> Self {
        Self { // <-- this thing here
            diameter: diameter,
            hole_diameter: None,
        }
    }

The project's minimum required version (v1.13) does not support this; find the new minimum required version and update:

  • .travis.yml's minimum version to test with.
  • README.md to reflect the new change in minimum required version.

To find the new minimal required version, instead of using rustup override, you can also just run cargo +1.13.0 test to test on 1.13.0 (or whatever version you want). Install new toolchains with rustup toolchain add <version>.

Derive Clone

...for all types where it makes sense (probably almost all).

Create constructors

...everywhere it makes sense.

As an example the Circle struct has these two constructors:

 pub struct Circle {
     pub diameter: f64,
     pub hole_diameter: Option<f64>,
 }

impl Circle {
    pub fn new(diameter: f64) -> Self {
        Circle {
            diameter: diameter,
            hole_diameter: None,
        }
    }
    pub fn with_hole(diameter: f64, hole_diameter: f64) -> Self {
        Circle {
            diameter: diameter,
           hole_diameter: Some(hole_diameter),
        }
    }
}

Some more complex objects might also benefit from the builder pattern.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.