Encode a `Value` into avro format. NOTE** This will not perform schema validation. The value is assumed to be valid with regards to the schema. Schema are needed only to guide the encoding for complex type values.
(value: &Value, schema: SchemaNode, buffer: &mut Vec<u8>)
| 62 | /// be valid with regards to the schema. Schema are needed only to guide the |
| 63 | /// encoding for complex type values. |
| 64 | pub fn encode_ref(value: &Value, schema: SchemaNode, buffer: &mut Vec<u8>) { |
| 65 | match value { |
| 66 | Value::Null => (), |
| 67 | Value::Boolean(b) => buffer.push(if *b { 1u8 } else { 0u8 }), |
| 68 | Value::Int(i) => encode_int(*i, buffer), |
| 69 | Value::Long(i) => encode_long(*i, buffer), |
| 70 | Value::Float(x) => buffer.extend_from_slice(&x.to_le_bytes()), |
| 71 | Value::Date(d) => encode_int(*d, buffer), |
| 72 | Value::Timestamp(d) => { |
| 73 | let mult = match schema.inner { |
| 74 | SchemaPiece::TimestampMilli => 1_000, |
| 75 | SchemaPiece::TimestampMicro => 1_000_000, |
| 76 | other => panic!("Invalid schema for timestamp: {:?}", other), |
| 77 | }; |
| 78 | let ts_seconds = d |
| 79 | .and_utc() |
| 80 | .timestamp() |
| 81 | .checked_mul(mult) |
| 82 | .expect("All chrono dates can be converted to timestamps"); |
| 83 | let sub_part: i64 = if mult == 1_000 { |
| 84 | d.and_utc().timestamp_subsec_millis().into() |
| 85 | } else { |
| 86 | d.and_utc().timestamp_subsec_micros().into() |
| 87 | }; |
| 88 | let ts = ts_seconds + sub_part; |
| 89 | encode_long(ts, buffer) |
| 90 | } |
| 91 | Value::Double(x) => buffer.extend_from_slice(&x.to_le_bytes()), |
| 92 | Value::Decimal(DecimalValue { unscaled, .. }) => match schema.name { |
| 93 | None => encode_bytes(unscaled, buffer), |
| 94 | Some(_) => { |
| 95 | // Fixed-size decimal: left-pad to exact size with two's-complement |
| 96 | // sign extension (0xFF for negative, 0x00 for non-negative). |
| 97 | if let SchemaPiece::Decimal { |
| 98 | fixed_size: Some(size), |
| 99 | .. |
| 100 | } = schema.inner |
| 101 | { |
| 102 | let is_negative = unscaled.first().map_or(false, |b| b & 0x80 != 0); |
| 103 | let pad = if is_negative { 0xFFu8 } else { 0x00u8 }; |
| 104 | let start = buffer.len(); |
| 105 | buffer.resize(start + size.saturating_sub(unscaled.len()), pad); |
| 106 | } |
| 107 | buffer.extend_from_slice(unscaled); |
| 108 | } |
| 109 | }, |
| 110 | Value::Bytes(bytes) => encode_bytes(bytes, buffer), |
| 111 | Value::String(s) => match schema.inner { |
| 112 | SchemaPiece::String => { |
| 113 | encode_bytes(s, buffer); |
| 114 | } |
| 115 | SchemaPiece::Enum { symbols, .. } => { |
| 116 | if let Some(index) = symbols.iter().position(|item| item == s) { |
| 117 | encode_int(index as i32, buffer); |
| 118 | } |
| 119 | } |
| 120 | _ => (), |
| 121 | }, |
no test coverage detected