Skip to content

Commit

Permalink
Merge pull request kaitai-io#250 from Agile86/rust_basic_support_v2
Browse files Browse the repository at this point in the history
Rust support
  • Loading branch information
generalmimon authored Sep 7, 2024
2 parents 8610e1d + d7c9516 commit 049b464
Show file tree
Hide file tree
Showing 5 changed files with 1,641 additions and 442 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ resolvers ++= Resolver.sonatypeOssRepos("public")

val NAME = "kaitai-struct-compiler"
val VERSION = "0.11-SNAPSHOT"
val TARGET_LANGS = "C++/STL, C#, Go, Java, JavaScript, Lua, Nim, Perl, PHP, Python, Ruby"
val TARGET_LANGS = "C++/STL, C#, Go, Java, JavaScript, Lua, Nim, Perl, PHP, Python, Ruby, Rust"
val UTF8 = Charset.forName("UTF-8")

lazy val root = project.in(file(".")).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.kaitai.struct.translators.TypeProvider

class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends TypeProvider {
var nowClass = topClass
val allClasses: ClassSpecs = classSpecs

var _currentIteratorType: Option[DataType] = None
var _currentSwitchType: Option[DataType] = None
Expand Down
48 changes: 34 additions & 14 deletions shared/src/main/scala/io/kaitai/struct/RustClassCompiler.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package io.kaitai.struct

import io.kaitai.struct.datatype.DataType.{KaitaiStreamType, UserTypeInstream}
import io.kaitai.struct.datatype.{Endianness, FixedEndian, InheritedEndian}
import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.datatype._
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format._
import io.kaitai.struct.languages.RustCompiler
import io.kaitai.struct.languages.components.ExtraAttrs
Expand Down Expand Up @@ -29,18 +30,19 @@ class RustClassCompiler(

// Basic struct declaration
lang.classHeader(curClass.name)

compileAttrDeclarations(curClass.seq ++ extraAttrs)
curClass.instances.foreach { case (instName, instSpec) =>
compileInstanceDeclaration(instName, instSpec)
}

// Constructor = Read() function
compileReadFunction(curClass)

compileInstances(curClass)

compileAttrReaders(curClass.seq ++ extraAttrs)
curClass.toStringExpr.foreach(expr => lang.classToString(expr))
lang.classFooter(curClass.name)

compileEnums(curClass)
Expand All @@ -49,7 +51,7 @@ class RustClassCompiler(
compileSubclasses(curClass)
}

def compileReadFunction(curClass: ClassSpec) = {
def compileReadFunction(curClass: ClassSpec): Unit = {
lang.classConstructorHeader(
curClass.name,
curClass.parentType,
Expand All @@ -58,23 +60,41 @@ class RustClassCompiler(
curClass.params
)

// FIXME
val defEndian = curClass.meta.endian match {
case Some(fe: FixedEndian) => Some(fe)
case _ => None
}

lang.readHeader(defEndian, false)


lang.readHeader(defEndian, isEmpty = false)

curClass.meta.endian match {
case Some(ce: CalcEndian) => compileCalcEndian(ce)
case Some(_) => // Nothing to generate
case None => // Same here
}

compileSeq(curClass.seq, defEndian)
lang.classConstructorFooter
}

override def compileInstances(curClass: ClassSpec) = {
override def compileCalcEndian(ce: CalcEndian): Unit = {
def renderProc(result: FixedEndian): Unit = {
val v = result match {
case LittleEndian => Ast.expr.IntNum(1)
case BigEndian => Ast.expr.IntNum(2)
}
lang.instanceCalculate(IS_LE_ID, CalcIntType, v)
}
lang.switchCases[FixedEndian](IS_LE_ID, ce.on, ce.cases, renderProc, renderProc)
lang.runReadCalc()
}

override def compileInstances(curClass: ClassSpec): Unit = {
lang.instanceDeclHeader(curClass.name)
curClass.instances.foreach { case (instName, instSpec) =>
compileInstance(curClass.name, instName, instSpec, curClass.meta.endian)
}
lang.instanceFooter
}

override def compileInstance(className: List[String], instName: InstanceIdentifier, instSpec: InstanceSpec, endian: Option[Endianness]): Unit = {
Expand All @@ -88,16 +108,16 @@ class RustClassCompiler(
lang.instanceHeader(className, instName, dataType, instSpec.isNullable)
lang.instanceCheckCacheAndReturn(instName, dataType)

lang.instanceSetCalculated(instName)
instSpec match {
case vi: ValueInstanceSpec =>
lang.attrParseIfHeader(instName, vi.ifExpr)
lang.instanceCalculate(instName, dataType, vi.value)
lang.attrParseIfFooter(vi.ifExpr)
case i: ParseInstanceSpec =>
lang.attrParse(i, instName, None) // FIXME
case pi: ParseInstanceSpec =>
lang.attrParse(pi, instName, None) // FIXME
}

lang.instanceSetCalculated(instName)
lang.instanceReturn(instName, dataType)
lang.instanceFooter
}
Expand Down
Loading

0 comments on commit 049b464

Please sign in to comment.