ianmackenzie/elm-iso-10303/5.0.0

NOTE: the latest version is 8.0.1

Formerly ianmackenzie/elm-step-file. Search finds this package by either name.

Step.Decode

This module lets you decode data from STEP files in a similar way to how you decode JSON.

Decoder types

type Decoder i a

A Decoder describes how to attempt to decode some input of type i (an entire file, an individual entity, a specific attribute) and produce some output of type a.

type File

Represents an entire STEP file composed of a header and a list of entities. The only way to extract data from a File is by using a decoder, so you'll likely never need to refer to or use this type directly.

type Error
= ParseError String
| NonexistentEntity Int
| CircularReference (List Int)
| DecodeError String

Different kinds of errors that may be encountered when loading a STEP file:

  • ParseError: the file could not be parsed as a valid STEP file.
  • NonexistentEntity: one entity in the STEP file refers to another by integer ID, but no entity with that ID exists in the file.
  • CircularReference: There exists a circular chain of entities in the file that refer to each other; the List Int is the list of entity IDs in the chain.
  • DecodeError: the file was parsed OK and all entity references were resolved successfully, but an error occurred when running the given decoder.

Decoding a file

file : Decoder File a -> String -> Result Error a

Decode a STEP file given as a String using the given decoder. For example, to extract the file header and all CARTESIAN_POINT entities from a given file, you might write:

import Step.Types as Step
import Step.Decode as Decode exposing (Decoder)


type alias FileData =
    { header : Step.Header
    , points : List ( Float, Float, Float )
    }


pointDecoder : Decoder Step.Entity ( Float, Float, Float )
pointDecoder =
    Decode.entity "CARTESIAN_POINT" <|
        Decode.attribute 1 (Decode.tuple3 Decode.float)


fileDecoder : Decoder Step.File FileData
fileDecoder =
    Decode.map2 FileData
        Decode.header
        (Decode.all pointDecoder)


fileContents : String
fileContents =
    "ISO-10303-21;...END-ISO-10303-21;"


decoded : Result Decode.Error FileData
decoded =
    Decode.file fileDecoder fileContents

Attempt to find exactly one entity in a file that matches the given decoder. If there are no matching entities or more than one matching entity, the decoder will fail.

all : Decoder Entity a -> Decoder File (List a)

Find all entities in a file matching the given decoder.

Top-level entities

It may be useful in some cases to only decode top-level entities (entities that are not referenced by any other entities). These otherwise work just like single and all.

Attempt to find exactly one top-level entity in a file that matches the given decoder.

Find all top-level entities in a file matching the given decoder.

Decoding an entity

entity : String -> Decoder (List Attribute) a -> Decoder Entity a

Decode an entity of the given type name, using the given decoder on the entity's list of attributes.

The decoder will skip any entities with a different type name. This means that, for example,

Decode.all <|
    Decode.entity "SOME_TYPE" <|
        Decode.attribute 0 attributeDecoder

will attempt to decode all entities of type SOME_TYPE and skip the rest.

Get the integer ID of a particular entity in a file. Note that these are not guaranteed to be consistent between two different versions of a given STEP file.

Decoding attributes

Decode a specific attribute by index (starting from 0) in an attribute list. To decode data from multiple attributes in a list, you can use one of the mapN functions, for example:

type alias MyAttributes =
    { name : String
    , age : Int
    , height : Float
    }


myAttributesDecoder : Decoder (List Attribute) MyAttributes
myAttributesDecoder =
    Decode.map3 MyAttributes
        (Decode.attribute 0 Decode.string)
        (Decode.attribute 1 Decode.int)
        (Decode.attribute 2 Decode.float)

Decode a single attribute as a Bool (from the special STEP enum values .T. and .F.).

Decode a single attribute as an Int.

Decode a single attribute as a Float. Note that unlike JSON, STEP has different encodings for Int and Float values so you cannot use this function to decode integer values; if you want to decode an integer value as a Float you will need to use

Decode.map toFloat Decode.int

Decode a single attribute as a String.

enum : List ( String, a ) -> Decoder Attribute a

Decode a single enum attribute, by passing a list of enum cases as their STEP type name and corresponding Elm value. For example, given a STEP enum with values RED, YELLOW and GREEN you might write:

type LightColor
    = Red
    | Yellow
    | Green


lightColorDecoder : Decoder Attribute LightColor
lightColorDecoder =
    Decode.enum
        [ ( "RED", Red )
        , ( "YELLOW", Yellow )
        , ( "GREEN", Green )
        ]

(Note that the given strings will be normalized, so case does not matter.)

Decode an attribute which is a reference to another entity, by providing the decoder to use for that entity.

binaryData : Decoder a -> Decoder Attribute a

Decode a single attribute as a blob of binary data, using the given binary decoder.

Decode the special 'null' attribute ($) as the given value.

Decode an attribute that may be null, returning Nothing if it is.

Decode an attribute as a list, passing the decoder to be used for each list item.

Decode a list of exactly two elements, passing the decoder to be used for the two elements.

Decode a list of exactly three elements, passing the decoder to be used for the three elements.

Decode the special 'derived value' attribute (*) as the given value.

Typed attributes

boolAs : String -> Decoder Attribute Bool

Decode a Bool wrapped as the given type.

intAs : String -> Decoder Attribute Int

Decode an Int wrapped as the given type.

floatAs : String -> Decoder Attribute Float

Decode a Float wrapped as the given type.

stringAs : String -> Decoder Attribute String

Decode a String wrapped as the given type.

enumAs : String -> List ( String, a ) -> Decoder Attribute a

Decode an enum wrapped as the given type.

binaryDataAs : String -> Decoder a -> Decoder Attribute a

Decode binary data wrapped as the given type.

Note that while the STEP format supports binary data with an arbitrary number of bits, Elm only supports byte-aligned binary data (where the number of bits is a multiple of eight). This means that the Bytes value passed to the decoder may be zero-padded. For example, if a STEP file contained a binary data attribute with the value 011001 (six bits), the Elm Bytes value that would actually end up being decoded would be 00011001 (eight bits/one byte).

listAs : String -> Decoder Attribute a -> Decoder Attribute (List a)

Decode a list wrapped as the given type.

Working with decoders

succeed : a -> Decoder i a

A special decoder that always succeeds with the given value. Primarily useful with andThen.

fail : String -> Decoder i a

A special decoder that always fails with the given error message.

map : (a -> b) -> Decoder i a -> Decoder i b

Map the value produced by a decoder.

map2 : (a -> b -> c) -> Decoder i a -> Decoder i b -> Decoder i c

Map over two decoders.

(a -> b -> c -> d)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d

Map over three decoders.

(a -> b -> c -> d -> e)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d
-> Decoder i e

Map over four decoders.

(a -> b -> c -> d -> e -> f)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d
-> Decoder i e
-> Decoder i f

Map over five decoders.

(a -> b -> c -> d -> e -> f -> g)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d
-> Decoder i e
-> Decoder i f
-> Decoder i g

Map over six decoders.

(a -> b -> c -> d -> e -> f -> g -> h)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d
-> Decoder i e
-> Decoder i f
-> Decoder i g
-> Decoder i h

Map over seven decoders.

(a -> b -> c -> d -> e -> f -> g -> h -> j)
-> Decoder i a
-> Decoder i b
-> Decoder i c
-> Decoder i d
-> Decoder i e
-> Decoder i f
-> Decoder i g
-> Decoder i h
-> Decoder i j

Map over eight decoders.

andThen : (a -> Decoder i b) -> Decoder i a -> Decoder i b

Run one decoder on some input, and based on the result of the first decoder decide what decoder to apply next to the same input.

Construct an entity decoder that may match one of many entity types. The first decoder with a matching type will be used. If none of the entity types match, then the current entity is skipped.

lazy : (() -> Decoder i a) -> Decoder i a

Define a decoder lazily such that it is only constructed if needed. This is primarily used to break circular reference chains between decoders.

A special decoder that just returns its input unmodified. This can be useful if you want to get a raw Entity or Attribute value and inspect it.