Crate foxglove_data_loader

Source
Expand description

Data Loaders are an experimental Extension API that allow you to support more file formats in Foxglove. You build a Data Loader as a Foxglove Extension using WASM.

To create a Data Loader, implement the DataLoader and MessageIterator traits, and make your Data Loader available using the export macro.

The compiled WASM blob can then be bundled with a Foxglove Extension to be installed in the Foxglove app. View the Data Loader template for an end-to-end example of bundling a Data Loader for use in Foxglove.

§Example

use foxglove_data_loader::*;
use std::io::{ BufReader, Read };

struct MyDataLoader { paths: Vec<String> }

impl DataLoader for MyDataLoader {
    // Your error type can be anything that can be converted into a boxed error.
    // This could be an `anyhow` or `thiserror` error, or even a `String`.
    type Error = String;
    // Foxglove will ask your Data Loader for multiple message iterators to fill the Foxglove
    // panels with data. You define a struct that implements [`MessageIterator`] to do this.
    type MessageIterator = MyMessageIterator;

    fn new(args: DataLoaderArgs) -> Self {
        // Data Loaders are created with a list of paths selected from the Foxglove app.
        // Keep them around so you can open them using the `reader` interface later.
        let DataLoaderArgs { paths } = args;
        Self { paths }
    }

    fn initialize(&mut self) -> Result<Initialization, Self::Error> {
        // Return an `Initialization` to tell Foxglove what your data looks like.
        let mut builder = Initialization::builder();

        // Open one of the provided paths:
        let mut file = BufReader::new(reader::open(&self.paths[0]));
        let mut buf = vec![ 0; 1024 ];
        // Read some data from your file:
        file.read(&mut buf)
            .expect("should be able to read");

        let great_channel = builder
            .add_channel("/my-great-channel")
            .message_count(10);

        // Keep track of this so you know when Foxglove requests `/my-great-channel`.
        let great_channel_id = great_channel.id();

        let init = builder
            .add_problem(Problem::warn("this is a warning about the data"))
            .build();

        Ok(init)
    }

    fn create_iter(&mut self, args: MessageIteratorArgs) ->
        Result<Self::MessageIterator, Self::Error> {
        // Return an iterator that will return messages for the requested channels
        // and time range.
        Ok(MyMessageIterator {
            current_nanos: args.start_time.unwrap_or(0),
            end_nanos: args.start_time.unwrap_or(u64::MAX),
            channels: args.channels
        })
    }
}

struct MyMessageIterator {
    channels: Vec<u16>,
    current_nanos: u64,
    end_nanos: u64
}

impl MessageIterator for MyMessageIterator {
    type Error = String;

    fn next(&mut self) -> Option<Result<Message, Self::Error>> {
        // When all the data for the time range has been read, return None.
        if self.current_nanos > self.end_nanos {
            return None;
        }

        // Return a message containing data from your file format.
        Some(Ok(Message {
            channel_id: 1,
            data: vec![ 1, 2, 3, 4 ],
            log_time: 100,
            publish_time: 100
        }))
    }
}

Modules§

console
Used to log to the host console.
reader
Used for reading files provided by the host to the Data Loader.

Macros§

export
Export a data loader to WASM output with this macro.

Structs§

BackfillArgs
Arguments to the get_backfill method.
Channel
A Channel groups related messages that have the same Schema. Each channel is identified by a unique topic name.
DataLoaderArgs
Arguments passed to the data loader constructor.
Initialization
Initializations are returned by DataLoader::initialize() and hold the set of channels and their corresponding schemas, the time range, and a set of problem messages.
InitializationBuilder
Builder interface for creating an Initialization with schemas and channels using automatically- assigned IDs.
LinkedChannel
Builder interface that links back to the originating LinkedSchema and InitializationBuilder
LinkedSchema
A LinkedSchema holds a foxglove::Schema plus the Channels that use this schema and message encoding.
Message
A Message is a timestamped log entry containing data from a recording
MessageIteratorArgs
Arguments to the create_iter method.
Problem
Problems can be used to display info in the “problems” panel during playback.
Schema
A Schema describes the structure of the contents of a Message

Enums§

Severity

Traits§

DataLoader
Implement this trait and call foxglove::data_loader_export() on your loader.
MessageIterator
Implement MessageIterator for your loader iterator.

Type Aliases§

ChannelId
SchemaId
TimeRange