1use std::collections::hash_map::DefaultHasher;
2use std::hash::Hash;
3use std::hash::Hasher;
4
5use crate::{KOSValueParseError, OpcodeParseError};
6
7#[derive(Debug, Clone)]
10pub struct BufferIterator<'a> {
11 index: usize,
12 source: &'a [u8],
13}
14
15impl<'a> BufferIterator<'a> {
16 pub fn new(source: &'a [u8]) -> Self {
18 Self { index: 0, source }
19 }
20
21 pub fn peek(&self) -> Option<u8> {
25 self.source.get(self.index).copied()
26 }
27
28 pub fn current_index(&self) -> usize {
30 self.index
31 }
32
33 pub fn collect_vec(self) -> Vec<u8> {
35 self.source.to_vec()
36 }
37
38 pub fn len(&self) -> usize {
40 self.source.len()
41 }
42
43 pub fn is_empty(&self) -> bool {
45 self.current_index() == self.source.len()
46 }
47}
48
49impl Iterator for BufferIterator<'_> {
50 type Item = u8;
51
52 fn next(&mut self) -> Option<Self::Item> {
53 let b = self.source.get(self.index).copied()?;
54
55 self.index += 1;
57
58 Some(b)
59 }
60
61 fn size_hint(&self) -> (usize, Option<usize>) {
62 (self.len(), Some(self.len()))
63 }
64}
65
66impl std::io::Read for BufferIterator<'_> {
67 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
68 self.source.read(buf)
69 }
70}
71
72pub trait WritableBuffer {
74 fn allocate_more(&mut self, amount: usize);
77 fn write(&mut self, val: u8);
79 fn write_bytes(&mut self, val: &[u8]);
81}
82
83impl WritableBuffer for Vec<u8> {
84 fn allocate_more(&mut self, amount: usize) {
85 self.try_reserve(amount).unwrap();
87 }
88
89 fn write(&mut self, val: u8) {
90 self.push(val);
91 }
92
93 fn write_bytes(&mut self, val: &[u8]) {
94 self.extend_from_slice(val);
95 }
96}
97
98pub trait ToBytes {
100 fn to_bytes(&self, buf: &mut impl WritableBuffer);
102}
103
104pub trait FromBytes {
106 type Error;
108 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error>
110 where
111 Self: Sized;
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
123#[repr(u8)]
124pub enum KOSType {
125 Null = 0,
127 Bool = 1,
129 Byte = 2,
131 Int16 = 3,
133 Int32 = 4,
135 Float = 5,
137 Double = 6,
139 String = 7,
141 ArgMarker = 8,
143 ScalarInt = 9,
145 ScalarDouble = 10,
147 BoolValue = 11,
149 StringValue = 12,
151}
152
153impl From<KOSType> for u8 {
154 fn from(t: KOSType) -> Self {
155 t as u8
156 }
157}
158
159impl TryFrom<u8> for KOSType {
160 type Error = ();
161
162 fn try_from(value: u8) -> Result<Self, Self::Error> {
163 match value {
164 0 => Ok(Self::Null),
165 1 => Ok(Self::Bool),
166 2 => Ok(Self::Byte),
167 3 => Ok(Self::Int16),
168 4 => Ok(Self::Int32),
169 5 => Ok(Self::Float),
170 6 => Ok(Self::Double),
171 7 => Ok(Self::String),
172 8 => Ok(Self::ArgMarker),
173 9 => Ok(Self::ScalarInt),
174 10 => Ok(Self::ScalarDouble),
175 11 => Ok(Self::BoolValue),
176 12 => Ok(Self::StringValue),
177 _ => Err(()),
178 }
179 }
180}
181
182impl ToBytes for KOSType {
183 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
184 (*self as u8).to_bytes(buf);
185 }
186}
187
188impl FromBytes for KOSType {
189 type Error = ();
190
191 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error>
192 where
193 Self: Sized,
194 {
195 Self::try_from(u8::from_bytes(source)?)
196 }
197}
198
199#[derive(Debug, Clone)]
213pub enum KOSValue {
214 Null,
216 Bool(bool),
218 Byte(i8),
220 Int16(i16),
222 Int32(i32),
224 Float(f32),
226 Double(f64),
228 String(String),
230 ArgMarker,
232 ScalarInt(i32),
234 ScalarDouble(f64),
236 BoolValue(bool),
238 StringValue(String),
240}
241
242impl KOSValue {
243 pub fn size_bytes(&self) -> usize {
245 match &self {
246 Self::Null | Self::ArgMarker => 1,
247 Self::Bool(_) | Self::Byte(_) | Self::BoolValue(_) => 2,
248 Self::Int16(_) => 3,
249 Self::Int32(_) | Self::Float(_) | Self::ScalarInt(_) => 5,
250 Self::Double(_) | Self::ScalarDouble(_) => 9,
251 Self::String(s) | Self::StringValue(s) => {
252 2 + s.len() }
254 }
255 }
256}
257
258impl Hash for KOSValue {
259 fn hash<H: Hasher>(&self, state: &mut H) {
260 match self {
261 Self::Null => 0.hash(state),
262 Self::Bool(b) => {
263 1.hash(state);
264 b.hash(state);
265 }
266 Self::Byte(b) => {
267 2.hash(state);
268 b.hash(state);
269 }
270 Self::Int16(i) => {
271 3.hash(state);
272 i.hash(state);
273 }
274 Self::Int32(i) => {
275 4.hash(state);
276 i.hash(state);
277 }
278 Self::Float(f) => {
279 5.hash(state);
280 f.to_bits().hash(state);
281 }
282 Self::Double(d) => {
283 6.hash(state);
284 d.to_bits().hash(state);
285 }
286 Self::String(s) => {
287 7.hash(state);
288 s.hash(state);
289 }
290 Self::ArgMarker => {
291 8.hash(state);
292 }
293 Self::ScalarInt(i) => {
294 9.hash(state);
295 i.hash(state);
296 }
297 Self::ScalarDouble(d) => {
298 10.hash(state);
299 d.to_bits().hash(state);
300 }
301 Self::BoolValue(b) => {
302 11.hash(state);
303 b.hash(state);
304 }
305 Self::StringValue(s) => {
306 12.hash(state);
307 s.hash(state);
308 }
309 }
310 }
311}
312
313impl PartialEq for KOSValue {
314 fn eq(&self, other: &Self) -> bool {
315 let mut hasher_1 = DefaultHasher::new();
316 self.hash(&mut hasher_1);
317 let mut hasher_2 = DefaultHasher::new();
318 other.hash(&mut hasher_2);
319
320 hasher_1.finish() == hasher_2.finish()
321 }
322}
323
324impl Eq for KOSValue {}
325
326impl ToBytes for KOSValue {
327 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
328 match self {
329 Self::Null => {
330 buf.write(0);
331 }
332 Self::Bool(b) => {
333 buf.write(1);
334 b.to_bytes(buf);
335 }
336 Self::Byte(b) => {
337 buf.write(2);
338 b.to_bytes(buf);
339 }
340 Self::Int16(i) => {
341 buf.write(3);
342 i.to_bytes(buf);
343 }
344 Self::Int32(i) => {
345 buf.write(4);
346 i.to_bytes(buf);
347 }
348 Self::Float(f) => {
349 buf.write(5);
350 f.to_bytes(buf);
351 }
352 Self::Double(f) => {
353 buf.write(6);
354 f.to_bytes(buf);
355 }
356 Self::String(s) => {
357 buf.write(7);
358 buf.write(s.len() as u8);
359 s.to_bytes(buf);
360 }
361 Self::ArgMarker => {
362 buf.write(8);
363 }
364 Self::ScalarInt(i) => {
365 buf.write(9);
366 i.to_bytes(buf);
367 }
368 Self::ScalarDouble(f) => {
369 buf.write(10);
370 f.to_bytes(buf);
371 }
372 Self::BoolValue(b) => {
373 buf.write(11);
374 b.to_bytes(buf);
375 }
376 Self::StringValue(s) => {
377 buf.write(12);
378 buf.write(s.len() as u8);
379 s.to_bytes(buf);
380 }
381 }
382 }
383}
384
385impl FromBytes for KOSValue {
386 type Error = KOSValueParseError;
387
388 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error>
389 where
390 Self: Sized,
391 {
392 let raw_type = source.next().ok_or(KOSValueParseError::EOF)?;
393 let kos_type =
394 KOSType::try_from(raw_type).map_err(|_| KOSValueParseError::InvalidType(raw_type))?;
395
396 match kos_type {
397 KOSType::Null => Ok(KOSValue::Null),
398 KOSType::Bool => bool::from_bytes(source).map(KOSValue::Bool),
399 KOSType::Byte => i8::from_bytes(source).map(KOSValue::Byte),
400 KOSType::Int16 => i16::from_bytes(source).map(KOSValue::Int16),
401 KOSType::Int32 => i32::from_bytes(source).map(KOSValue::Int32),
402 KOSType::Float => f32::from_bytes(source).map(KOSValue::Float),
403 KOSType::Double => f64::from_bytes(source).map(KOSValue::Double),
404 KOSType::String => String::from_bytes(source).map(KOSValue::String),
405 KOSType::ArgMarker => Ok(KOSValue::ArgMarker),
406 KOSType::ScalarInt => i32::from_bytes(source).map(KOSValue::ScalarInt),
407 KOSType::ScalarDouble => f64::from_bytes(source).map(KOSValue::ScalarDouble),
408 KOSType::BoolValue => bool::from_bytes(source).map(KOSValue::BoolValue),
409 KOSType::StringValue => String::from_bytes(source).map(KOSValue::StringValue),
410 }
411 .map_err(|_| KOSValueParseError::EOF)
412 }
413}
414
415impl ToBytes for bool {
416 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
417 buf.write(if *self { 1 } else { 0 });
418 }
419}
420
421impl ToBytes for u8 {
422 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
423 buf.write(*self);
424 }
425}
426
427impl ToBytes for i8 {
428 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
429 buf.write((*self) as u8);
430 }
431}
432
433impl ToBytes for u16 {
434 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
435 buf.write_bytes(&self.to_le_bytes());
436 }
437}
438
439impl ToBytes for i16 {
440 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
441 buf.write_bytes(&self.to_le_bytes());
442 }
443}
444
445impl ToBytes for u32 {
446 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
447 buf.write_bytes(&self.to_le_bytes());
448 }
449}
450
451impl ToBytes for i32 {
452 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
453 buf.write_bytes(&self.to_le_bytes());
454 }
455}
456
457impl ToBytes for f32 {
458 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
459 buf.write_bytes(&self.to_le_bytes());
460 }
461}
462
463impl ToBytes for f64 {
464 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
465 buf.write_bytes(&self.to_le_bytes());
466 }
467}
468
469impl ToBytes for &str {
470 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
471 buf.write_bytes(self.as_bytes());
472 }
473}
474
475impl ToBytes for String {
476 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
477 buf.write_bytes(self.as_bytes());
478 }
479}
480
481impl FromBytes for bool {
482 type Error = ();
483
484 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
485 source.next().map(|x| x != 0).ok_or(())
486 }
487}
488
489impl FromBytes for u8 {
490 type Error = ();
491
492 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
493 source.next().ok_or(())
494 }
495}
496
497impl FromBytes for i8 {
498 type Error = ();
499
500 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
501 source.next().map(|x| x as i8).ok_or(())
502 }
503}
504
505impl FromBytes for u16 {
506 type Error = ();
507
508 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
509 let mut slice = [0u8; 2];
510 for b in &mut slice {
511 if let Some(byte) = source.next() {
512 *b = byte;
513 } else {
514 return Err(());
515 }
516 }
517 Ok(u16::from_le_bytes(slice))
518 }
519}
520
521impl FromBytes for i16 {
522 type Error = ();
523
524 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
525 let mut slice = [0u8; 2];
526 for b in &mut slice {
527 if let Some(byte) = source.next() {
528 *b = byte;
529 } else {
530 return Err(());
531 }
532 }
533 Ok(i16::from_le_bytes(slice))
534 }
535}
536
537impl FromBytes for u32 {
538 type Error = ();
539
540 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
541 let mut slice = [0u8; 4];
542 for b in &mut slice {
543 if let Some(byte) = source.next() {
544 *b = byte;
545 } else {
546 return Err(());
547 }
548 }
549 Ok(u32::from_le_bytes(slice))
550 }
551}
552
553impl FromBytes for i32 {
554 type Error = ();
555
556 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
557 let mut slice = [0u8; 4];
558 for b in &mut slice {
559 if let Some(byte) = source.next() {
560 *b = byte;
561 } else {
562 return Err(());
563 }
564 }
565 Ok(i32::from_le_bytes(slice))
566 }
567}
568
569impl FromBytes for f32 {
570 type Error = ();
571
572 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
573 let mut slice = [0u8; 4];
574 for b in &mut slice {
575 if let Some(byte) = source.next() {
576 *b = byte;
577 } else {
578 return Err(());
579 }
580 }
581 Ok(f32::from_le_bytes(slice))
582 }
583}
584
585impl FromBytes for f64 {
586 type Error = ();
587
588 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
589 let mut slice = [0u8; 8];
590 for b in &mut slice {
591 if let Some(byte) = source.next() {
592 *b = byte;
593 } else {
594 return Err(());
595 }
596 }
597 Ok(f64::from_le_bytes(slice))
598 }
599}
600
601impl FromBytes for String {
602 type Error = ();
603
604 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
605 let len = source.next().ok_or(())? as usize;
606 let mut s = String::with_capacity(len);
607 for _ in 0..len {
608 if let Some(byte) = source.next() {
609 s.push(byte as char);
610 } else {
611 return Err(());
612 }
613 }
614 Ok(s)
615 }
616}
617
618#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
635pub enum Opcode {
636 Bogus,
638 Eof,
640 Eop,
642 Nop,
644 Sto,
646 Uns,
648 Gmb,
650 Smb,
652 Gidx,
654 Sidx,
656 Bfa,
658 Jmp,
660 Add,
662 Sub,
664 Mul,
666 Div,
668 Pow,
670 Cgt,
674 Clt,
678 Cge,
682 Cle,
686 Ceq,
688 Cne,
690 Neg,
692 Bool,
696 Not,
700 And,
702 Or,
704 Call,
708 Ret,
710 Push,
712 Pop,
714 Dup,
716 Swap,
718 Eval,
721 Addt,
723 Rmvt,
725 Wait,
727 Gmet,
729 Stol,
732 Stog,
735 Bscp,
737 Escp,
739 Stoe,
742 Phdl,
744 Btr,
746 Exst,
748 Argb,
750 Targ,
752 Tcan,
754 Prl,
756 Pdrl,
758 Lbrt,
760
761 Pushv,
765}
766
767impl Opcode {
768 pub fn num_operands(&self) -> usize {
770 match self {
771 Opcode::Eof => 0,
772 Opcode::Eop => 0,
773 Opcode::Nop => 0,
774 Opcode::Sto => 1,
775 Opcode::Uns => 0,
776 Opcode::Gmb => 1,
777 Opcode::Smb => 1,
778 Opcode::Gidx => 0,
779 Opcode::Sidx => 0,
780 Opcode::Bfa => 1,
781 Opcode::Jmp => 1,
782 Opcode::Add => 0,
783 Opcode::Sub => 0,
784 Opcode::Mul => 0,
785 Opcode::Div => 0,
786 Opcode::Pow => 0,
787 Opcode::Cgt => 0,
788 Opcode::Clt => 0,
789 Opcode::Cge => 0,
790 Opcode::Cle => 0,
791 Opcode::Ceq => 0,
792 Opcode::Cne => 0,
793 Opcode::Neg => 0,
794 Opcode::Bool => 0,
795 Opcode::Not => 0,
796 Opcode::And => 0,
797 Opcode::Or => 0,
798 Opcode::Call => 2,
799 Opcode::Ret => 1,
800 Opcode::Push => 1,
801 Opcode::Pop => 0,
802 Opcode::Dup => 0,
803 Opcode::Swap => 0,
804 Opcode::Eval => 0,
805 Opcode::Addt => 2,
806 Opcode::Rmvt => 0,
807 Opcode::Wait => 0,
808 Opcode::Gmet => 1,
809 Opcode::Stol => 1,
810 Opcode::Stog => 1,
811 Opcode::Bscp => 2,
812 Opcode::Escp => 1,
813 Opcode::Stoe => 1,
814 Opcode::Phdl => 2,
815 Opcode::Btr => 1,
816 Opcode::Exst => 0,
817 Opcode::Argb => 0,
818 Opcode::Targ => 0,
819 Opcode::Tcan => 0,
820
821 Opcode::Prl => 1,
822 Opcode::Pdrl => 2,
823 Opcode::Lbrt => 1,
824
825 Opcode::Pushv => 1,
826
827 Opcode::Bogus => 0,
828 }
829 }
830}
831
832impl From<u8> for Opcode {
833 fn from(byte: u8) -> Self {
834 match byte {
835 0x31 => Opcode::Eof,
836 0x32 => Opcode::Eop,
837 0x33 => Opcode::Nop,
838 0x34 => Opcode::Sto,
839 0x35 => Opcode::Uns,
840 0x36 => Opcode::Gmb,
841 0x37 => Opcode::Smb,
842 0x38 => Opcode::Gidx,
843 0x39 => Opcode::Sidx,
844 0x3a => Opcode::Bfa,
845 0x3b => Opcode::Jmp,
846 0x3c => Opcode::Add,
847 0x3d => Opcode::Sub,
848 0x3e => Opcode::Mul,
849 0x3f => Opcode::Div,
850 0x40 => Opcode::Pow,
851 0x41 => Opcode::Cgt,
852 0x42 => Opcode::Clt,
853 0x43 => Opcode::Cge,
854 0x44 => Opcode::Cle,
855 0x45 => Opcode::Ceq,
856 0x46 => Opcode::Cne,
857 0x47 => Opcode::Neg,
858 0x48 => Opcode::Bool,
859 0x49 => Opcode::Not,
860 0x4a => Opcode::And,
861 0x4b => Opcode::Or,
862 0x4c => Opcode::Call,
863 0x4d => Opcode::Ret,
864 0x4e => Opcode::Push,
865 0x4f => Opcode::Pop,
866 0x50 => Opcode::Dup,
867 0x51 => Opcode::Swap,
868 0x52 => Opcode::Eval,
869 0x53 => Opcode::Addt,
870 0x54 => Opcode::Rmvt,
871 0x55 => Opcode::Wait,
872 0x57 => Opcode::Gmet,
873 0x58 => Opcode::Stol,
874 0x59 => Opcode::Stog,
875 0x5a => Opcode::Bscp,
876 0x5b => Opcode::Escp,
877 0x5c => Opcode::Stoe,
878 0x5d => Opcode::Phdl,
879 0x5e => Opcode::Btr,
880 0x5f => Opcode::Exst,
881 0x60 => Opcode::Argb,
882 0x61 => Opcode::Targ,
883 0x62 => Opcode::Tcan,
884
885 0xce => Opcode::Prl,
886 0xcd => Opcode::Pdrl,
887 0xf0 => Opcode::Lbrt,
888
889 0xfa => Opcode::Pushv,
890
891 _ => Opcode::Bogus,
892 }
893 }
894}
895
896impl From<Opcode> for u8 {
897 fn from(opcode: Opcode) -> Self {
898 match opcode {
899 Opcode::Bogus => 0x00,
900 Opcode::Eof => 0x31,
901 Opcode::Eop => 0x32,
902 Opcode::Nop => 0x33,
903 Opcode::Sto => 0x34,
904 Opcode::Uns => 0x35,
905 Opcode::Gmb => 0x36,
906 Opcode::Smb => 0x37,
907 Opcode::Gidx => 0x38,
908 Opcode::Sidx => 0x39,
909 Opcode::Bfa => 0x3a,
910 Opcode::Jmp => 0x3b,
911 Opcode::Add => 0x3c,
912 Opcode::Sub => 0x3d,
913 Opcode::Mul => 0x3e,
914 Opcode::Div => 0x3f,
915 Opcode::Pow => 0x40,
916 Opcode::Cgt => 0x41,
917 Opcode::Clt => 0x42,
918 Opcode::Cge => 0x43,
919 Opcode::Cle => 0x44,
920 Opcode::Ceq => 0x45,
921 Opcode::Cne => 0x46,
922 Opcode::Neg => 0x47,
923 Opcode::Bool => 0x48,
924 Opcode::Not => 0x49,
925 Opcode::And => 0x4a,
926 Opcode::Or => 0x4b,
927 Opcode::Call => 0x4c,
928 Opcode::Ret => 0x4d,
929 Opcode::Push => 0x4e,
930 Opcode::Pop => 0x4f,
931 Opcode::Dup => 0x50,
932 Opcode::Swap => 0x51,
933 Opcode::Eval => 0x52,
934 Opcode::Addt => 0x53,
935 Opcode::Rmvt => 0x54,
936 Opcode::Wait => 0x55,
937 Opcode::Gmet => 0x57,
938 Opcode::Stol => 0x58,
939 Opcode::Stog => 0x59,
940 Opcode::Bscp => 0x5a,
941 Opcode::Escp => 0x5b,
942 Opcode::Stoe => 0x5c,
943 Opcode::Phdl => 0x5d,
944 Opcode::Btr => 0x5e,
945 Opcode::Exst => 0x5f,
946 Opcode::Argb => 0x60,
947 Opcode::Targ => 0x61,
948 Opcode::Tcan => 0x62,
949
950 Opcode::Prl => 0xce,
951 Opcode::Pdrl => 0xcd,
952 Opcode::Lbrt => 0xf0,
953
954 Opcode::Pushv => 0xfa,
955 }
956 }
957}
958
959impl From<&str> for Opcode {
960 fn from(s: &str) -> Self {
961 match s {
962 "eof" => Opcode::Eof,
963 "eop" => Opcode::Eop,
964 "nop" => Opcode::Nop,
965 "sto" => Opcode::Sto,
966 "uns" => Opcode::Uns,
967 "gmb" => Opcode::Gmb,
968 "smb" => Opcode::Smb,
969 "gidx" => Opcode::Gidx,
970 "sidx" => Opcode::Sidx,
971 "bfa" => Opcode::Bfa,
972 "jmp" => Opcode::Jmp,
973 "add" => Opcode::Add,
974 "sub" => Opcode::Sub,
975 "mul" => Opcode::Mul,
976 "div" => Opcode::Div,
977 "pow" => Opcode::Pow,
978 "cgt" => Opcode::Cgt,
979 "clt" => Opcode::Clt,
980 "cge" => Opcode::Cge,
981 "cle" => Opcode::Cle,
982 "ceq" => Opcode::Ceq,
983 "cne" => Opcode::Cne,
984 "neg" => Opcode::Neg,
985 "bool" => Opcode::Bool,
986 "not" => Opcode::Not,
987 "and" => Opcode::And,
988 "or" => Opcode::Or,
989 "call" => Opcode::Call,
990 "ret" => Opcode::Ret,
991 "push" => Opcode::Push,
992 "pop" => Opcode::Pop,
993 "dup" => Opcode::Dup,
994 "swap" => Opcode::Swap,
995 "eval" => Opcode::Eval,
996 "addt" => Opcode::Addt,
997 "rmvt" => Opcode::Rmvt,
998 "wait" => Opcode::Wait,
999 "gmet" => Opcode::Gmet,
1000 "stol" => Opcode::Stol,
1001 "stog" => Opcode::Stog,
1002 "bscp" => Opcode::Bscp,
1003 "escp" => Opcode::Escp,
1004 "stoe" => Opcode::Stoe,
1005 "phdl" => Opcode::Phdl,
1006 "btr" => Opcode::Btr,
1007 "exst" => Opcode::Exst,
1008 "argb" => Opcode::Argb,
1009 "targ" => Opcode::Targ,
1010 "tcan" => Opcode::Tcan,
1011
1012 "prl" => Opcode::Prl,
1013 "pdrl" => Opcode::Pdrl,
1014 "lbrt" => Opcode::Lbrt,
1015
1016 "pushv" => Opcode::Pushv,
1017 &_ => Opcode::Bogus,
1018 }
1019 }
1020}
1021
1022impl From<Opcode> for &str {
1023 fn from(opcode: Opcode) -> Self {
1024 match opcode {
1025 Opcode::Eof => "eof",
1026 Opcode::Eop => "eop",
1027 Opcode::Nop => "nop",
1028 Opcode::Sto => "sto",
1029 Opcode::Uns => "uns",
1030 Opcode::Gmb => "gmb",
1031 Opcode::Smb => "smb",
1032 Opcode::Gidx => "gidx",
1033 Opcode::Sidx => "sidx",
1034 Opcode::Bfa => "bfa",
1035 Opcode::Jmp => "jmp",
1036 Opcode::Add => "add",
1037 Opcode::Sub => "sub",
1038 Opcode::Mul => "mul",
1039 Opcode::Div => "div",
1040 Opcode::Pow => "pow",
1041 Opcode::Cgt => "cgt",
1042 Opcode::Clt => "clt",
1043 Opcode::Cge => "cge",
1044 Opcode::Cle => "cle",
1045 Opcode::Ceq => "ceq",
1046 Opcode::Cne => "cne",
1047 Opcode::Neg => "neg",
1048 Opcode::Bool => "bool",
1049 Opcode::Not => "not",
1050 Opcode::And => "and",
1051 Opcode::Or => "or",
1052 Opcode::Call => "call",
1053 Opcode::Ret => "ret",
1054 Opcode::Push => "push",
1055 Opcode::Pop => "pop",
1056 Opcode::Dup => "dup",
1057 Opcode::Swap => "swap",
1058 Opcode::Eval => "eval",
1059 Opcode::Addt => "addt",
1060 Opcode::Rmvt => "rmvt",
1061 Opcode::Wait => "wait",
1062 Opcode::Gmet => "gmet",
1063 Opcode::Stol => "stol",
1064 Opcode::Stog => "stog",
1065 Opcode::Bscp => "bscp",
1066 Opcode::Escp => "escp",
1067 Opcode::Stoe => "stoe",
1068 Opcode::Phdl => "phdl",
1069 Opcode::Btr => "btr",
1070 Opcode::Exst => "exst",
1071 Opcode::Argb => "argb",
1072 Opcode::Targ => "targ",
1073 Opcode::Tcan => "tcan",
1074
1075 Opcode::Prl => "prl",
1076 Opcode::Pdrl => "pdrl",
1077 Opcode::Lbrt => "lbrt",
1078
1079 Opcode::Pushv => "pushv",
1080
1081 Opcode::Bogus => "bogus",
1082 }
1083 }
1084}
1085
1086impl ToBytes for Opcode {
1087 fn to_bytes(&self, buf: &mut impl WritableBuffer) {
1088 buf.write((*self).into());
1089 }
1090}
1091
1092impl FromBytes for Opcode {
1093 type Error = OpcodeParseError;
1094
1095 fn from_bytes(source: &mut BufferIterator) -> Result<Self, Self::Error> {
1096 let value = source.next().ok_or(OpcodeParseError::EOF)?;
1097 let opcode = Opcode::from(value);
1098
1099 match opcode {
1100 Opcode::Bogus => Err(OpcodeParseError::InvalidOpcode(value)),
1101 _ => Ok(opcode),
1102 }
1103 }
1104}
1105
1106#[cfg(test)]
1107mod tests {
1108 use super::*;
1109
1110 #[test]
1111 fn null_to_bytes() {
1112 let v = KOSValue::Null;
1113
1114 let mut buf = Vec::with_capacity(1);
1115
1116 v.to_bytes(&mut buf);
1117
1118 assert_eq!(buf, vec![0]);
1119 }
1120
1121 #[test]
1122 fn bool_to_bytes() {
1123 let v1 = KOSValue::Bool(true);
1124 let v2 = KOSValue::Bool(false);
1125
1126 let mut buf = Vec::with_capacity(2);
1127
1128 v1.to_bytes(&mut buf);
1129
1130 assert_eq!(buf, vec![1, 1]);
1131
1132 buf.clear();
1133 v2.to_bytes(&mut buf);
1134
1135 assert_eq!(buf, vec![1, 0]);
1136 }
1137
1138 #[test]
1139 fn byte_to_bytes() {
1140 let v1 = KOSValue::Byte(0);
1141 let v2 = KOSValue::Byte(-128);
1142
1143 let mut buf = Vec::with_capacity(2);
1144
1145 v1.to_bytes(&mut buf);
1146
1147 assert_eq!(buf, vec![2, 0]);
1148
1149 buf.clear();
1150 v2.to_bytes(&mut buf);
1151
1152 assert_eq!(buf, vec![2, -128i8 as u8]);
1153 }
1154
1155 #[test]
1156 fn int16_to_bytes() {
1157 let v1 = KOSValue::Int16(526);
1158
1159 let mut buf = Vec::with_capacity(3);
1160
1161 v1.to_bytes(&mut buf);
1162
1163 assert_eq!(buf, vec![3, 0b00001110, 0b00000010]);
1164 }
1165
1166 #[test]
1167 fn int32_to_bytes() {
1168 let v1 = KOSValue::Int32(-764);
1169
1170 let mut buf = Vec::with_capacity(5);
1171
1172 v1.to_bytes(&mut buf);
1173
1174 assert_eq!(buf, vec![4, 0b00000100, 0b11111101, 0b11111111, 0b11111111]);
1175 }
1176
1177 #[test]
1178 fn float_to_bytes() {
1179 let v1 = KOSValue::Float(3.14159);
1180
1181 let mut buf = Vec::with_capacity(5);
1182
1183 v1.to_bytes(&mut buf);
1184
1185 assert_eq!(buf, vec![5, 208, 15, 73, 64]);
1186 }
1187
1188 #[test]
1189 fn double_to_bytes() {
1190 let v1 = KOSValue::Double(3.14159);
1191
1192 let mut buf = Vec::with_capacity(9);
1193
1194 v1.to_bytes(&mut buf);
1195
1196 assert_eq!(buf, vec![6, 110, 134, 27, 240, 249, 33, 9, 64]);
1197 }
1198
1199 #[test]
1200 fn string_to_bytes() {
1201 let v1 = KOSValue::String(String::from("test str"));
1202
1203 let mut buf = Vec::with_capacity(10);
1204
1205 v1.to_bytes(&mut buf);
1206
1207 assert_eq!(
1208 buf,
1209 vec![7, 8, b't', b'e', b's', b't', b' ', b's', b't', b'r']
1210 );
1211 }
1212
1213 #[test]
1214 fn argmarker_to_bytes() {
1215 let v1 = KOSValue::ArgMarker;
1216
1217 let mut buf = Vec::with_capacity(1);
1218
1219 v1.to_bytes(&mut buf);
1220
1221 assert_eq!(buf, vec![8]);
1222 }
1223
1224 #[test]
1225 fn scalarint_to_bytes() {
1226 let v1 = KOSValue::ScalarInt(-1267);
1227
1228 let mut buf = Vec::with_capacity(5);
1229
1230 v1.to_bytes(&mut buf);
1231
1232 assert_eq!(buf, vec![9, 0b00001101, 0b11111011, 0b11111111, 0b11111111]);
1233 }
1234
1235 #[test]
1236 fn scalardouble_to_bytes() {
1237 let v1 = KOSValue::ScalarDouble(3.14159);
1238
1239 let mut buf = Vec::with_capacity(9);
1240
1241 v1.to_bytes(&mut buf);
1242
1243 assert_eq!(buf, vec![10, 110, 134, 27, 240, 249, 33, 9, 64]);
1244 }
1245
1246 #[test]
1247 fn boolvalue_to_bytes() {
1248 let v1 = KOSValue::BoolValue(true);
1249 let v2 = KOSValue::BoolValue(false);
1250
1251 let mut buf = Vec::with_capacity(2);
1252
1253 v1.to_bytes(&mut buf);
1254
1255 assert_eq!(buf, vec![11, 1]);
1256
1257 buf.clear();
1258 v2.to_bytes(&mut buf);
1259
1260 assert_eq!(buf, vec![11, 0]);
1261 }
1262
1263 #[test]
1264 fn stringvalue_to_bytes() {
1265 let v1 = KOSValue::StringValue(String::from("hello"));
1266
1267 let mut buf = Vec::with_capacity(7);
1268
1269 v1.to_bytes(&mut buf);
1270
1271 assert_eq!(buf, vec![12, 5, b'h', b'e', b'l', b'l', b'o']);
1272 }
1273}