mathlex 0.4.1

Mathematical expression parser for LaTeX and plain text notation, producing a language-agnostic AST
Documentation
/// MathLexExpression+DecodableExtra.swift
/// Set theory, tensor, and differential-form decode helpers for MathLexExpression.
///
/// Split from MathLexExpression+Decodable.swift to keep file sizes within limits.

import Foundation

extension MathLexExpression {


  // MARK: Set theory

  private static func decodeSetTheory(
    from c: KeyedDecodingContainer<MathLexTopKey>
  ) throws -> MathLexExpression? {
    if c.contains(.SetOperation) {
      struct P: Decodable {
        let op: SetOp
        let left, right: MathLexExpression
      }
      let p = try c.decode(P.self, forKey: .SetOperation)
      return .setOperation(op: p.op, left: p.left, right: p.right)
    }
    if c.contains(.SetRelationExpr) {
      struct P: Decodable {
        let relation: SetRelation
        let element, set: MathLexExpression
      }
      let p = try c.decode(P.self, forKey: .SetRelationExpr)
      return .setRelationExpr(relation: p.relation, element: p.element, set: p.set)
    }
    if c.contains(.SetBuilder) {
      struct P: Decodable {
        let variable: String
        let domain: MathLexExpression?
        let predicate: MathLexExpression
      }
      let p = try c.decode(P.self, forKey: .SetBuilder)
      return .setBuilder(variable: p.variable, domain: p.domain, predicate: p.predicate)
    }
    if c.contains(.PowerSet) {
      struct P: Decodable { let set: MathLexExpression }
      return .powerSet(set: try c.decode(P.self, forKey: .PowerSet).set)
    }
    return nil
  }

  // MARK: Tensors, differential forms, and function algebra

  private static func decodeTensorsAndForms(
    from c: KeyedDecodingContainer<MathLexTopKey>
  ) throws -> MathLexExpression? {
    if c.contains(.Tensor) {
      struct P: Decodable {
        let name: String
        let indices: [TensorIndex]
      }
      let p = try c.decode(P.self, forKey: .Tensor)
      return .tensor(name: p.name, indices: p.indices)
    }
    if c.contains(.KroneckerDelta) {
      struct P: Decodable { let indices: [TensorIndex] }
      return .kroneckerDelta(indices: try c.decode(P.self, forKey: .KroneckerDelta).indices)
    }
    if c.contains(.LeviCivita) {
      struct P: Decodable { let indices: [TensorIndex] }
      return .leviCivita(indices: try c.decode(P.self, forKey: .LeviCivita).indices)
    }
    if c.contains(.FunctionSignature) {
      struct P: Decodable {
        let name: String
        let domain, codomain: MathLexExpression
      }
      let p = try c.decode(P.self, forKey: .FunctionSignature)
      return .functionSignature(name: p.name, domain: p.domain, codomain: p.codomain)
    }
    if c.contains(.Composition) {
      struct P: Decodable { let outer, inner: MathLexExpression }
      let p = try c.decode(P.self, forKey: .Composition)
      return .composition(outer: p.outer, inner: p.inner)
    }
    if c.contains(.Differential) {
      struct P: Decodable { let `var`: String }
      return .differential(var: try c.decode(P.self, forKey: .Differential).var)
    }
    if c.contains(.WedgeProduct) {
      struct P: Decodable { let left, right: MathLexExpression }
      let p = try c.decode(P.self, forKey: .WedgeProduct)
      return .wedgeProduct(left: p.left, right: p.right)
    }
    if c.contains(.Relation) {
      struct P: Decodable {
        let op: RelationOp
        let left, right: MathLexExpression
      }
      let p = try c.decode(P.self, forKey: .Relation)
      return .relation(op: p.op, left: p.left, right: p.right)
    }
    return nil
}