diff --git a/.gitignore b/.gitignore index b63da45..2abd8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/ .idea/jarRepositories.xml .idea/compiler.xml .idea/libraries/ +.idea/misc.xml *.iws *.iml *.ipr diff --git a/.idea/misc.xml b/.idea/misc.xml index 9879958..5304681 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt index 412c3d0..207a914 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt @@ -20,7 +20,7 @@ internal data class BarCode( } override val command: CharSequence = "^B1" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "o" to orientation.code, "c" to checkDigit.toString(), "h" to height, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt index 4632a77..2c2454a 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt @@ -18,7 +18,7 @@ internal data class FieldBlock( } override val command: CharSequence = "^FB" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "w" to width, "l" to maxLines, "s" to lineSpacing, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt index cb05247..f9b4465 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt @@ -4,7 +4,7 @@ import com.sainsburys.k2zpl.builder.ZplBuilder internal data class FieldData(val data: String) : ZplCommand { override val command: CharSequence = "^FD" - override val parameters: Map = addParameters("d" to data) + override val parameters: ZplParameters = zplParameters("d" to data) override fun build(stringBuilder: StringBuilder): StringBuilder { return stringBuilder diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt index 1321442..4918e6c 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt @@ -14,7 +14,7 @@ internal data class FieldOrigin( } override val command: CharSequence = "^FO" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "x" to x, "y" to y, "j" to justification diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt index 11e6708..8704f3e 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt @@ -17,8 +17,8 @@ internal data class Font( } override val command: CharSequence = "^A${font}" - override val parameters: Map = - addParameters("o" to orientation, "h" to height, "w" to width) + override val parameters: ZplParameters = + zplParameters("o" to orientation, "h" to height, "w" to width) } diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt index 092318c..a402e40 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt @@ -18,8 +18,8 @@ internal data class GraphicBox( } override val command: CharSequence = "^GB" - override val parameters: Map = - addParameters( + override val parameters: ZplParameters = + zplParameters( "w" to width, "h" to height, "t" to thickness, "c" to color.code, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt index 1790078..5c6d9d8 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt @@ -17,7 +17,7 @@ internal data class GraphicField( } override val command: CharSequence = "^GF" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "f" to format, "db" to dataBytes, "tb" to totalBytes, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt index 2d48acf..3d791e8 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt @@ -4,7 +4,7 @@ import com.sainsburys.k2zpl.builder.ZplBuilder internal data class LabelHome(val x: Int, val y: Int) : ZplCommand { override val command: CharSequence = "^LH" - override val parameters: Map = addParameters("x" to x, "y" to y) + override val parameters: ZplParameters = zplParameters("x" to x, "y" to y) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt index 94df7d7..40d3cf9 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt @@ -8,7 +8,7 @@ internal data class LabelLength(val length: Int) : ZplCommand { } override val command: CharSequence = "^LL" - override val parameters: Map = addParameters("l" to length) + override val parameters: ZplParameters = zplParameters("l" to length) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt index 15d7e4d..6dfe6ed 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt @@ -10,8 +10,8 @@ internal data class MediaMode( val prePeelSelect: ZplYesNo ) : ZplCommand { override val command: CharSequence = "^MM" - override val parameters: Map = - addParameters("m" to mediaMode, "p" to prePeelSelect) + override val parameters: ZplParameters = + zplParameters("m" to mediaMode, "p" to prePeelSelect) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt index 4fa69f5..35d5fde 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt @@ -8,7 +8,7 @@ internal data class PrintWidth(val width: Int) : ZplCommand { } override val command: CharSequence = "^PW" - override val parameters: Map = addParameters("w" to width) + override val parameters: ZplParameters = zplParameters("w" to width) } diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt index ec45921..285f447 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt @@ -2,31 +2,13 @@ package com.sainsburys.k2zpl.command interface ZplCommand { val command: CharSequence - val parameters: Map get() = addParameters() + val parameters: ZplParameters get() = zplParameters() fun build(stringBuilder: StringBuilder) = stringBuilder.apply { append(command) - with(parameters.values.iterator()) { - if (hasNext()) { - nextNotNull { append(it.toString()) } - } - while (hasNext()) { - nextNotNull { - if (length > command.length) { - append(',') - } - append(it.toString()) - } - } - } + parameters + .asSequence() + .mapNotNull { it.value?.toString() } + .filter(String::isNotBlank) + .joinTo(this, separator = ",") } } - -private fun Iterator.nextNotNull(block: (T) -> Unit) { - next()?.let { block(it) } -} - -/** - * A shortcut to adding parameters that helps to enforce use of [LinkedHashMap] - * so that entry order is preserved. - */ -internal fun ZplCommand.addParameters(vararg pairs: Pair) = linkedMapOf(*pairs) diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/ZplParameters.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplParameters.kt new file mode 100644 index 0000000..78fc7a3 --- /dev/null +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplParameters.kt @@ -0,0 +1,12 @@ +package com.sainsburys.k2zpl.command + +class ZplParameters(map: Map) : Iterable> { + constructor(vararg pairs: Pair) : this(mapOf(*pairs)) + private val _parameters: LinkedHashMap = LinkedHashMap(map) + operator fun get(key: CharSequence) = _parameters[key] + override fun iterator(): Iterator> = + _parameters.iterator() +} + +fun zplParameters(vararg pairs: Pair) = ZplParameters(*pairs) +fun zplParameters(builderBlock: MutableMap.() -> Unit) = ZplParameters(buildMap(builderBlock)) \ No newline at end of file diff --git a/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt index 0046bb5..084152c 100644 --- a/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt +++ b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt @@ -33,14 +33,14 @@ class ZplCommandWithoutParameters : ZplCommand { class ZplCommandWithOneParameter : ZplCommand { override val command = "^ZCP" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "param-one" to "value-one" ) } class ZplCommandWithMultipleParameters : ZplCommand { override val command = "^ZCPS" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "param-one" to "value-one", "param-two" to "value-two" ) @@ -48,7 +48,7 @@ class ZplCommandWithMultipleParameters : ZplCommand { class ZplCommandWitNullFirstParameter : ZplCommand { override val command = "^ZCPN" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "param-one" to null, "param-two" to "value-two" ) @@ -56,7 +56,7 @@ class ZplCommandWitNullFirstParameter : ZplCommand { class ZplCommandWitNullSecondParameter : ZplCommand { override val command = "^ZCPNS" - override val parameters: Map = addParameters( + override val parameters: ZplParameters = zplParameters( "param-one" to "value-one", "param-two" to null ) diff --git a/src/test/kotlin/com/sainsburys/k2zpl/command/ZplParametersTest.kt b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplParametersTest.kt new file mode 100644 index 0000000..56cc040 --- /dev/null +++ b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplParametersTest.kt @@ -0,0 +1,73 @@ +package com.sainsburys.k2zpl.command + +import io.kotest.core.spec.IsolationMode +import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe + +class ZplParametersTest : DescribeSpec({ + isolationMode = IsolationMode.InstancePerLeaf + + describe("ZplParameters pairs constructor") { + val result = ZplParameters("a" to "b", "c" to "d") + it("returns values passed to ZplParameters") { + result.forEachIndexed { index, param -> + when (index) { + 0 -> param.value shouldBe "b" + 1 -> param.value shouldBe "d" + } + } + } + it("makes values accessible by get operator") { + result["a"] shouldBe "b" + result["c"] shouldBe "d" + } + } + describe("ZplParameters map constructor") { + val result = ZplParameters(mapOf("a" to "b", "c" to "d")) + it("returns values passed to ZplParameters") { + result.forEachIndexed { index, param -> + when (index) { + 0 -> param.value shouldBe "b" + 1 -> param.value shouldBe "d" + } + } + } + it("makes values accessible by get operator") { + result["a"] shouldBe "b" + result["c"] shouldBe "d" + } + } + describe("zplParameters pairs function") { + val result = zplParameters("e" to "f", "g" to "h") + it("returns values passed to ZplParameters") { + result.forEachIndexed { index, param -> + when (index) { + 0 -> param.value shouldBe "f" + 1 -> param.value shouldBe "h" + } + } } + it("makes values accessible by get operator") { + result["e"] shouldBe "f" + result["g"] shouldBe "h" + } + } + + describe("ZplParameters builder function") { + val result = zplParameters { + put("a", "b") + put("c", "d") + } + it("returns values passed to ZplParameters") { + result.forEachIndexed { index, param -> + when (index) { + 0 -> param.value shouldBe "b" + 1 -> param.value shouldBe "d" + } + } + } + it("makes values accessible by get operator") { + result["a"] shouldBe "b" + result["c"] shouldBe "d" + } + } +}) \ No newline at end of file