use lilv::{node::Node, plugin::Plugin, port::FloatRanges, World}; struct Nodes { control_class: Node, event_class: Node, group_pred: Node, label_pred: Node, preset_class: Node, designation_pred: Node, supports_event_pred: Node, } fn print_port(p: &Plugin, index: usize, port_ranges: &FloatRanges, nodes: &Nodes) { let port = p.port_by_index(index); println!("\n\tPort {}:", index); if port.is_none() { println!("\t\tERROR: Illegal/nonexistent port"); return; } let port = port.unwrap(); print!("\t\tType: "); for (i, value) in port.classes().iter().enumerate() { if i != 0 { print!("\n\t\t "); } print!("{}", value.as_uri().unwrap()); } if port.is_a(&nodes.event_class) { let supported = port.value(&nodes.supports_event_pred); if supported.count() > 0 { println!("\n\t\tSupported events:\n"); for value in supported { println!("\t\t\t{}", value.as_uri().unwrap()); } } } let points = port.scale_points(); println!("\n\t\tScale Points:"); for point in points { println!( "\t\t\t{} = \"{}\"", point.value().as_str().unwrap(), point.label().as_str().unwrap(), ); } println!( "\n\t\tSymbol: {}", port.symbol().unwrap().as_str().unwrap(), ); println!( "\t\tName: {}", port.name().unwrap().as_str().unwrap(), ); let groups = port.value(&nodes.group_pred); if let Some(group) = groups.iter().next() { println!("\t\tGroup: {}", group.as_str().unwrap(),); } let designations = port.value(&nodes.designation_pred); if let Some(designation) = designations.iter().next() { println!("\t\tDesignation: {}", designation.as_str().unwrap(),); } if port.is_a(&nodes.control_class) { let (min, max, def) = (port_ranges.min, port_ranges.max, port_ranges.default); if !min.is_nan() { println!("\t\tMinimum: {}", min); } if !max.is_nan() { println!("\t\tMaximum: {}", max); } if !def.is_nan() { println!("\t\tDefault: {}", def); } let properties = port.properties(); for (i, property) in properties.iter().enumerate() { if i != 0 { print!("\t\t "); } println!("{}", property.as_uri().unwrap()); } println!(); } } #[allow(clippy::too_many_lines)] fn print_plugin(world: &World, p: &Plugin, nodes: &Nodes) { println!("{}\n", p.uri().as_uri().unwrap()); println!("\tName: {}", p.name().as_str().unwrap()); println!( "\tClass: {}", p.class().label().as_str().unwrap() ); if let Some(val) = p.author_name() { println!("\tAuthor: {}", val.as_str().unwrap()); } if let Some(val) = p.author_email() { println!("\tAuthor Email: {}", val.as_str().unwrap()); } if let Some(val) = p.author_homepage() { println!("\tAuthor Homepage: {}", val.as_uri().unwrap()); } if let Some(latency_port) = p.latency_port_index() { println!( "\tHas latency: yes, reported by port {}", latency_port ); } else { println!("\tHas latency: no"); } println!("\tBundle: {}", p.bundle_uri().as_uri().unwrap()); println!( "\tBinary: {}", p.library_uri().map_or("".to_string(), |node| node .as_uri() .unwrap() .to_string()) ); if let Some(uis) = p.uis() { println!("\tUIs:"); for ui in uis { println!("\t\t{}", ui.uri().as_uri().unwrap()); for tyep in ui.classes() { println!("\t\t\tClass: {}", tyep.as_uri().unwrap()); } println!( "\t\t\tBinary: {}", ui.binary_uri().unwrap().as_uri().unwrap() ); println!( "\t\t\tBundle: {}", ui.bundle_uri().unwrap().as_uri().unwrap() ); } } print!("\tData URIs: "); for (i, uri) in p.data_uris().iter().enumerate() { if i != 0 { print!("\n\t "); } print!("{}", uri.as_uri().unwrap()); } println!(); let features = p.required_features(); print!("\tRequired Features: "); for (i, feature) in features.iter().enumerate() { if i != 0 { print!("\n\t "); } print!("{}", feature.as_uri().unwrap()); } println!(); let features = p.optional_features(); print!("\tOptional Features: "); for (i, feature) in features.iter().enumerate() { if i != 0 { print!("\n\t "); } print!("{}", feature.as_uri().unwrap()); } println!(); if let Some(data) = p.extension_data() { print!("\tExtension Data: "); for (i, d) in data.iter().enumerate() { if i != 0 { print!("\n\t "); } print!("{}", d.as_uri().unwrap()); } println!(); } if let Some(presets) = p.related(Some(&nodes.preset_class)) { if presets.count() != 0 { println!("\tPresets: "); for preset in presets { world.load_resource(&preset).unwrap(); let titles = world.find_nodes(Some(&preset), &nodes.label_pred, None); if titles.count() > 0 { if let Some(title) = titles.iter().next() { println!("\t {}", title.as_str().unwrap()); } else { println!("\t <{}>", preset.as_uri().unwrap()); } } else { println!("\t <{}>", preset.as_uri().unwrap()); } } } } let num_ports = p.ports_count(); let port_ranges = p.port_ranges_float(); assert_eq!(num_ports, port_ranges.len()); for (i, pr) in port_ranges.iter().enumerate() { print_port(p, i, pr, nodes); } } fn main() { let w = World::new(); w.load_all(); let nodes = Nodes { control_class: w.new_uri("http://lv2plug.in/ns/lv2core#ControlPort"), event_class: w.new_uri("http://lv2plug.in/ns/ext/atom#AtomPort"), group_pred: w.new_uri("http://lv2plug.in/ns/ext/port-groups#group"), label_pred: w.new_uri("http://www.w3.org/2000/01/rdf-schema#label"), preset_class: w.new_uri("http://lv2plug.in/ns/ext/presets#Preset"), designation_pred: w.new_uri("http://lv2plug.in/ns/lv2core#designation"), supports_event_pred: w.new_uri("http://lv2plug.in/ns/ext/atom#supportsEvent"), }; for p in w.plugins().iter().filter(Plugin::verify) { print_plugin(&w, &p, &nodes); } }