1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
910use std::path::PathBuf;
11use std::process;
1213use anyhow::Context;
14use mz_interchange::avro::Decoder;
15use mz_interchange::confluent;
16use mz_ore::cli;
17use mz_ore::cli::CliConfig;
18use mz_ore::error::ErrorExt;
19use tokio::fs;
2021/// Decode a single Avro row using Materialize's Avro decoder.
22#[derive(clap::Parser)]
23struct Args {
24/// The path to a file containing the raw bytes of a single Avro datum.
25data_file: PathBuf,
26/// The path to a file containing the Avro schema.
27schema_file: PathBuf,
28/// Whether the data file uses the Confluent wire format.
29#[clap(long)]
30confluent_wire_format: bool,
31}
3233#[tokio::main]
34async fn main() {
35let args: Args = cli::parse_args(CliConfig::default());
36if let Err(e) = run(args).await {
37println!("{}", e.display_with_causes());
38 process::exit(1);
39 }
40}
4142async fn run(args: Args) -> Result<(), anyhow::Error> {
43let mut data = &*fs::read(&args.data_file)
44 .await
45.context("reading data file")?;
46if args.confluent_wire_format {
47let (schema_id, adjusted_data) = confluent::extract_avro_header(data)?;
48 data = adjusted_data;
49println!("schema id: {schema_id}");
50 }
51let schema = fs::read_to_string(&args.schema_file)
52 .await
53.context("reading schema file")?;
54let ccsr_client: Option<mz_ccsr::Client> = None;
55let debug_name = String::from("avro-decode");
56let confluent_wire_format = false;
57let mut decoder = Decoder::new(&schema, ccsr_client, debug_name, confluent_wire_format)
58 .context("creating decoder")?;
59let row = decoder.decode(&mut data).await.context("decoding data")?;
60println!("row: {row:?}");
61Ok(())
62}