Skip to content

Commit 049b464

Browse files
authored
Merge pull request #250 from Agile86/rust_basic_support_v2
Rust support
2 parents 8610e1d + d7c9516 commit 049b464

File tree

5 files changed

+1641
-442
lines changed

5 files changed

+1641
-442
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ resolvers ++= Resolver.sonatypeOssRepos("public")
88

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

1414
lazy val root = project.in(file(".")).

shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.kaitai.struct.translators.TypeProvider
99

1010
class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends TypeProvider {
1111
var nowClass = topClass
12+
val allClasses: ClassSpecs = classSpecs
1213

1314
var _currentIteratorType: Option[DataType] = None
1415
var _currentSwitchType: Option[DataType] = None

shared/src/main/scala/io/kaitai/struct/RustClassCompiler.scala

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package io.kaitai.struct
22

3-
import io.kaitai.struct.datatype.DataType.{KaitaiStreamType, UserTypeInstream}
4-
import io.kaitai.struct.datatype.{Endianness, FixedEndian, InheritedEndian}
3+
import io.kaitai.struct.datatype.DataType._
4+
import io.kaitai.struct.datatype._
5+
import io.kaitai.struct.exprlang.Ast
56
import io.kaitai.struct.format._
67
import io.kaitai.struct.languages.RustCompiler
78
import io.kaitai.struct.languages.components.ExtraAttrs
@@ -29,18 +30,19 @@ class RustClassCompiler(
2930

3031
// Basic struct declaration
3132
lang.classHeader(curClass.name)
32-
33+
3334
compileAttrDeclarations(curClass.seq ++ extraAttrs)
3435
curClass.instances.foreach { case (instName, instSpec) =>
3536
compileInstanceDeclaration(instName, instSpec)
3637
}
37-
38+
3839
// Constructor = Read() function
3940
compileReadFunction(curClass)
40-
41+
4142
compileInstances(curClass)
4243

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

4648
compileEnums(curClass)
@@ -49,7 +51,7 @@ class RustClassCompiler(
4951
compileSubclasses(curClass)
5052
}
5153

52-
def compileReadFunction(curClass: ClassSpec) = {
54+
def compileReadFunction(curClass: ClassSpec): Unit = {
5355
lang.classConstructorHeader(
5456
curClass.name,
5557
curClass.parentType,
@@ -58,23 +60,41 @@ class RustClassCompiler(
5860
curClass.params
5961
)
6062

61-
// FIXME
6263
val defEndian = curClass.meta.endian match {
6364
case Some(fe: FixedEndian) => Some(fe)
6465
case _ => None
6566
}
66-
67-
lang.readHeader(defEndian, false)
68-
67+
68+
lang.readHeader(defEndian, isEmpty = false)
69+
70+
curClass.meta.endian match {
71+
case Some(ce: CalcEndian) => compileCalcEndian(ce)
72+
case Some(_) => // Nothing to generate
73+
case None => // Same here
74+
}
75+
6976
compileSeq(curClass.seq, defEndian)
7077
lang.classConstructorFooter
7178
}
7279

73-
override def compileInstances(curClass: ClassSpec) = {
80+
override def compileCalcEndian(ce: CalcEndian): Unit = {
81+
def renderProc(result: FixedEndian): Unit = {
82+
val v = result match {
83+
case LittleEndian => Ast.expr.IntNum(1)
84+
case BigEndian => Ast.expr.IntNum(2)
85+
}
86+
lang.instanceCalculate(IS_LE_ID, CalcIntType, v)
87+
}
88+
lang.switchCases[FixedEndian](IS_LE_ID, ce.on, ce.cases, renderProc, renderProc)
89+
lang.runReadCalc()
90+
}
91+
92+
override def compileInstances(curClass: ClassSpec): Unit = {
7493
lang.instanceDeclHeader(curClass.name)
7594
curClass.instances.foreach { case (instName, instSpec) =>
7695
compileInstance(curClass.name, instName, instSpec, curClass.meta.endian)
7796
}
97+
lang.instanceFooter
7898
}
7999

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

111+
lang.instanceSetCalculated(instName)
91112
instSpec match {
92113
case vi: ValueInstanceSpec =>
93114
lang.attrParseIfHeader(instName, vi.ifExpr)
94115
lang.instanceCalculate(instName, dataType, vi.value)
95116
lang.attrParseIfFooter(vi.ifExpr)
96-
case i: ParseInstanceSpec =>
97-
lang.attrParse(i, instName, None) // FIXME
117+
case pi: ParseInstanceSpec =>
118+
lang.attrParse(pi, instName, None) // FIXME
98119
}
99120

100-
lang.instanceSetCalculated(instName)
101121
lang.instanceReturn(instName, dataType)
102122
lang.instanceFooter
103123
}

0 commit comments

Comments
 (0)