oslquery-petite

Crates.iooslquery-petite
lib.rsoslquery-petite
version0.1.1
created_at2025-09-26 21:27:59.378275+00
updated_at2025-09-26 21:49:10.448409+00
descriptionQuery Open Shading Language (OSL) shader parameters & metadata
homepage
repositoryhttps://github.com/AcademySoftwareFoundation/OpenShadingLanguage
max_upload_size
id1856666
size134,151
Moritz Mœller (virtualritz)

documentation

README

oslquery-petite

A lightweight Rust crate for parsing and querying OSL (Open Shading Language) shader parameters & metadata from compiled .oso files. Aims to match OSL's liboslquery in the feature subset it implements 1:1.

Overview

oslquery-petite can parse OSO files generated by OSL compilers and extract shader parameters, types, default values, and metadata.

Features

  • Parse OSO files from OSL 1.00+ format.
  • Extract shader parameters with complete type information.
  • Compatible with 3Delight, Cycles, and other OSL implementations.
  • oslq (like oslinfo) CLI tool for querying shaders.

Installation

Add to your Cargo.toml:

[dependencies]
oslquery-petite = "0.1"

With optional features:

[dependencies]
oslquery-petite = { version = "0.1", features = ["cli", "json", "hash"] }

Features

  • json - Enables JSON serialization support.
  • hash - Derives Hash for all public types.

Quick Start

use oslquery_petite::{OslQuery, TypedParameter};

// Parse an OSO file.
let query = OslQuery::open("shader.oso")?;

// Get shader information.
println!("Shader: {} ({})", query.shader_name(), query.shader_type());
println!("Parameters: {}", query.param_count());

// Iterate through parameters with type-safe access.
for param in query.params() {
    println!("  {}", param.name);
    match param.typed_param() {
        TypedParameter::Float { default } => {
            if let Some(val) = default {
                println!("    float = {}", val);
            }
        }
        TypedParameter::Color { default, .. } => {
            if let Some([r, g, b]) = default {
                println!("    color = [{}, {}, {}]", r, g, b);
            }
        }
        TypedParameter::String { default } => {
            if let Some(s) = default {
                println!("    string = \"{}\"", s);
            }
        }
        _ => {}
    }
}

Type-Safe API

The API provides complete type safety where types and values are unified:

use oslquery_petite::{OslQuery, TypedParameter};

let query = OslQuery::open("shader.oso")?;
for param in query.params() {
    match param.typed_param() {
        TypedParameter::Color { default: Some([r, g, b]), .. } => {
            println!("Color: ({}, {}, {})", r, g, b);
        }
        TypedParameter::Float { default: Some(val) } => {
            println!("Float: {}", val);
        }
        TypedParameter::FloatArray { size, default: Some(vals) } => {
            println!("Float[{}]: {:?}", size, vals);
        }
        _ => {}
    }
}

The API prevents type mismatches – a Color parameter always has exactly 3 floats, a Matrix always has 16. You can't accidentally mix types with different defaults.

API Overview

OslQuery

The main entry point for querying shader information:

// Parse from file.
let query = OslQuery::open("shader.oso")?;

// Parse from string.
let content = std::fs::read_to_string("shader.oso")?;
let query = OslQuery::from_string(&content)?;

// Query shader info.
let name = query.shader_name();        // e.g., "lambert"
let shader_type = query.shader_type(); // e.g., "surface"
let param_count = query.param_count();

// Access parameters.
let param = query.param_by_name("Kd"); // By name
let param = query.param_at(0);          // By index
let all_params = query.params();        // All parameters

Parameter

Represents a shader parameter with type-safe access:

pub struct Parameter {
    pub name: Ustr,                   // Parameter name
    pub metadata: Vec<Metadata>,      // Metadata hints
    // Private fields encapsulate the typed parameter
}

impl Parameter {
    pub fn typed_param(&self) -> &TypedParameter;
    pub fn is_output(&self) -> bool;
    pub fn find_metadata(&self, name: &str) -> Option<&Metadata>;
}

TypedParameter

Type-safe parameter representation where type and (default) value are unified:

pub enum TypedParameter {
    Int { default: Option<i32> },
    Float { default: Option<f32> },
    String { default: Option<String> },
    Color { default: Option<[f32; 3]>, space: Option<Ustr> },
    Point { default: Option<[f32; 3]>, space: Option<Ustr> },
    Vector { default: Option<[f32; 3]>, space: Option<Ustr> },
    Normal { default: Option<[f32; 3]>, space: Option<Ustr> },
    Matrix { default: Option<[f32; 16]> },
    IntArray { size: usize, default: Option<Vec<i32>> },
    FloatArray { size: usize, default: Option<Vec<f32>> },
    StringArray { size: usize, default: Option<Vec<String>> },
    // ... and dynamic arrays, closure types, etc.
}

oslq – A Petite oslinfo Clone

# Query a shader.
oslq shader.oso

# Query multiple shaders/
oslq shader1.oso shader2.oso

# Query specific parameter.
oslq --param Kd shader.oso

# Use search path.
oslq -p /path/to/shaders:./local shader

# Verbose output.
oslq -v shader.oso

# JSON output (requires json feature).
oslq --json shader.oso

# Benchmark parsing.
oslq --runstats shader.oso

Examples

Parsing with Shader Search Path

use oslquery_petite::OslQuery;

// Search for shader.oso in multiple directories.
let searchpath = "/usr/local/shaders:/project/shaders";
let query = OslQuery::open_with_searchpath("shader", searchpath)?;

Checking for Specific Metadata

use oslquery_petite::MetadataValue;

for param in query.params() {
    // Check for UI hints.
    if let Some(label) = param.find_metadata("label") {
        if let MetadataValue::String(s) = &label.value {
            println!("UI Label: {}", s);
        }
    }

    // Check for help text.
    if let Some(help) = param.find_metadata("help") {
        if let MetadataValue::String(s) = &help.value {
            println!("Help: {}", s);
        }
    }
}

Arrays Handling

for param in query.params() {
    match param.typed_param() {
        TypedParameter::FloatArray { size, .. } => {
            println!("{} is a float array of size {}", param.name, size);
        }
        TypedParameter::FloatDynamicArray { .. } => {
            println!("{} is a variable-length float array", param.name);
        }
        TypedParameter::ColorArray { size, .. } => {
            println!("{} is a color array of size {}", param.name, size);
        }
        _ => {}
    }
}

Differences from C++ liboslquery

While maintaining API compatibility where possible, this Rust implementation:

  • Uses idiomatic Rust patterns (Result types, iterators, etc.).
  • Supports incremental parsing.
  • Has optional JSON serialization.
  • Smaller binary size and faster compilation.

License

Licensed under Apache-2.0 or BSD-3-Clause or MIT or Zlib at your option.

Contributing

Contributions are welcome! Please ensure:

  • All tests pass with cargo test.
  • Code is formatted with cargo fmt.
  • No clippy warnings with cargo clippy -- -W warnings.
  • Documentation is updated for API changes.

Acknowledgments

Based on the OSL specification and inspired by with Open Shading Language's liboslquery/oslinfo.

Commit count: 0

cargo fmt