How to parse xsd using xsd-parser-rs? - rust

Do you know how to parse xsd file into Rust structs using https://github.com/lumeohq/xsd-parser-rs?
I do not know how to run the program and how to put files there.

Here's a basic example that parses a file sample.xsd and then prints out the debug representation of the parsed result:
src/main.rs:
use anyhow::{format_err, Result};
use std::fs;
use xsd_parser::parser::parse as xsd_parse;
fn main() -> Result<()> {
let sample = fs::read_to_string("sample.xsd")?;
let parsed = xsd_parse(&sample).map_err(|_| format_err!("failed to parse XSD file"))?;
println!("{:#?}", &parsed);
Ok(())
}
Cargo.toml:
[package]
name = "xsd-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1"
xsd-parser = { git = "https://github.com/lumeohq/xsd-parser-rs", rev = "7f3d433e4f033b55f057e97c0a30de221dbe3ae1" }
sample.xsd:
I used the sample XSD file from here.
From the project folder, you can invoke rustdoc like cargo doc -p xsd-parser --no-deps --open to generate and open the API docs for the xsd-parser crate, which is what allowed me to figure out how to use the crate.

Related

Patch.crates-io is not applied

I am using serde-xml-rs crate in our project and I need to modify some code from that crate, so what I did is to generate a patch file, and apply it by calling cargo patch. In my Cargo.toml has stuff like following:
serde-xml-rs = "0.6.0"
[package.metadata.patch.serde-xml-rs]
version = "0.6.0"
patches = [
"patches/0001.patch"
]
[patch.crates-io]
serde-xml-rs = { path = "./target/patch/serde-xml-rs-0.6.0" }
When I called cargo run, project still use original version of serde-xml-rs instead of using values in patch.crates-io tag
But I could see that my patch is applied correctly to the target folder "./target/patch/serde-xml-rs-0.6.0", because if I modify toml file to following, it worked.
{ path = "./target/patch/serde-xml-rs-0.6.0" }

Unable to generate .so file for solana deployment. (No errors)

I am trying to understand the solana/example-helloworld by re-writing the rust lib myself. I have done this and from the package.json file, to generate the .so file, following is what is run:
cargo build-bpf --manifest-path=./src/program-rust/Cargo.toml --bpf-out-dir=dist/program
I used above since I already have cargo setup locally and run above against my setup, I faced a few issues, from the edition (was using 2021, had to downgrade to 2018) to having to rename main.rs to lib.rs and others I can't remember.
Below is my actual running command from the terminal in the project root directory where the Cargo.toml file is in:
cargo build-bpf --manifest-path=./Cargo.toml --bpf-out-dir=dist/program
But upon running above, in the dist directory, there is nothing
This is actually a multi-tied question:
.so file are signifies solana files, right?
What do we mean by cargo build-bpf?
Is there any reason, why 2021 edition didn't work for the solana example?
Finally, why does the above command not output my .so file?
My Cargo.toml below:
[package]
name = "jjoek-sc"
version = "0.0.1"
description = "My first rust program for solana (hello john)"
authors = ["JJoek <info#jjoek.com>"]
license = "Apache-2.0"
homepage = "https://jjoek.com/"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
borsh = "0.9.1"
borsh-derive = "0.9.1"
solana-program = "~1.8.14"
Below is my lib.rs
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
msg,
program_error::ProgramError,
};
/// Define the type of state stored in accounts
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct GreetingAccount {
/// number of greetings
pub counter: u32,
}
// Declare and export the program's entrypoint
entrypoint!(process_instruction);
// Program entrypoint's implementation
pub fn process_instruction(program_id: &Pubkey, accounts: &[AccountInfo], _instruction_data: &[u8]) -> ProgramResult {
msg!("Hello, John everything is gonna be okay");
msg!("Hello World Rust program entrypoint");
// Iterating accounts is safer than indexing
let accounts_iter = &mut accounts.iter();
// Get the account to say hello to
let account = next_account_info(accounts_iter)?;
// The account must be owned by the program in order to modify its data
if account.owner != program_id {
msg!("Greeted account does not have the correct program id");
return Err(ProgramError::IncorrectProgramId);
}
// Increment and store the number of times the account has been greeted
let mut greeting_account = GreetingAccount::try_from_slice(&account.data.borrow())?;
greeting_account.counter += 1;
greeting_account.serialize(&mut &mut account.data.borrow_mut()[..])?;
msg!("Greeted {} time(s)!", greeting_account.counter);
Ok(())
}
.so file are signifies solana files, right?
so stand for shared object, also known as a dynamically relocatable library or dylib in Cargo.toml.
What do we mean by cargo build-bpf?
BPF is a virtual machine inside the kernel, so this should instruct cargo to build for that target.
Is there any reason, why 2021 edition didn't work for the solana example?
I don't know, but I suspect it's a simple fix.
Finally, why does the above command not output my .so file?
Could it be that you are missing the lib section in Cargo.toml:
[lib]
crate-type = ["cdylib", "lib"]

what should I do if the project name contains hyphen in rust

I am a newbie of rust, when I tried to write a rust web api, but the project contains hyphen so I could not use it, if the project name like diesel_demo , I could use it like this:
use diesel_demo::schema::posts::dsl::*;
but if my project name like diesel-demo, what should I do to use it? I can not change my project name now with hyphen reddwarf-music. I read the docs and tell me the cargo will trans the - to _ by default, so I am use it like this:
use reddwarf_music::schema::posts::dsl::*;
but shows error like this:
~/Documents/GitHub/reddwarf-music on  develop! ⌚ 17:56:51
$ cargo build ‹ruby-2.7.2›
Compiling hello-rocket v0.1.0 (/Users/dolphin/Documents/GitHub/reddwarf-music)
error[E0433]: failed to resolve: use of undeclared crate or module `reddwarf_music`
--> src/biz/music/music.rs:1:5
|
1 | use reddwarf_music::schema::posts::dsl::*;
| ^^^^^^^^^^^^^^ use of undeclared crate or module `reddwarf_music`
what should I do handle the - in rust? By the way the scheme is generate in my local src, not from third package. This is my project structure:
this is my Cargo.toml:
[package]
name = "reddwarf_music"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket = { version = "0.5.0-rc.1", features = ["json"] }
rand = "0.8.4"
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
reqwest = "0.11.4"
# database
diesel = { version = "1.4.4", features = ["postgres"] }
dotenv = "0.15.0"
Within a crate you don't use the crates name with use, rather, you refer to the crate itself using the identifier crate.
So inside your crate "reddwarf-music", when you want to use an internal symbol, instead of writing
use reddwarf_music::schema::posts::dsl::*;
you write
use crate::schema::posts::dsl::*;

Cargo activates features by itself

I have a binary that depends on a library. In the library I specified these features:
[features]
default = []
fet = []
I would expect feature fet would ONLY be activated when it is compiled with the feature flag. In my binary the Cargo.toml looks like this:
[dependencies]
a = { path = "./a" }
[features]
default = []
I haven't specified the fet feature in the Cargo.toml, however this gives me a compilation error in my binary:
fn main() {
if cfg!(feature = "fet") {
compile_error!("not expected");
}
}
Why is feature fet still activated in my binary? I executed these commands and get the same error:
cargo run
cargo run --features=default
Ideally, I want my binary to activate certain features from dependencies if they are explicitly mentioned in the cargo run command (in the --features flag). Is this possible? I was hoping this would work in my binary Cargo.toml:
[features]
default = []
fet = ["a/fet"]
and feature fet would be activated if I ran this command:
cargo run --features=fet
The cfg! macro will be expanded to true or false depending on if the condition is true or false, so if the feature flag is not set, it will still expand to this:
fn main() {
if false {
compile_error!("not expected");
}
}
The compile_error! macro will still be invoked, so you'll get the compiler error either way.
The cfg! macro is mostly useful when you can rely on the compiler optimizing away branches that will never be taken, such as an if false branch. The code still needs to compile before optimization, though, so it's less useful when the code will only compile if the condition is true or false.
What you'd want to use instead is either a #[cfg] attribute or the cfg_if::cfg_if! macro:
// with #[cfg] attribute
fn main() {
#[cfg(feature = "fet")]
compile_error!("not expected");
}
// with cfg_if!
use cfg_if::cfg_if;
fn main() {
cfg_if!{
if #[cfg(feature = "fet")] {
compile_error!("not expected");
}
}
}

How to import substrate_primitives in order to use sr25519?

I have the following dependencies in my Cargo.toml file:
[package]
name = "api-client-tutorial"
version = "0.1.0"
authors = ["Supercomputing Systems AG <info#scs.ch>"]
edition = "2018"
[dependencies]
substrate-api-client = { git = "https://github.com/scs/substrate-api-client.git" }
codec = { package = "parity-scale-codec", features = ["derive"], version = "1.0.0", default-features = false }
[dependencies.primitives]
git = "https://github.com/paritytech/substrate"
rev = "3bf9540e72df5ecb3955845764dfee7dcdbb26b5"
package = "substrate-primitives"
[dependencies.keyring]
git = "https://github.com/paritytech/substrate"
rev = "3bf9540e72df5ecb3955845764dfee7dcdbb26b5"
package = "substrate-keyring"
I am unsure of the difference between dependencies section and dependencies.primitives section, but the package substrate-primitives is included in the primitives section.
I have seen that substrate_primitives has the module sr25519 I need to use, but when I try to import it in my code:
use substrate_api_client::{Api, node_metadata};
use substrate_primitives::sr25519;
fn main() {
// instantiate an Api that connects to the given address
let url = "127.0.0.1:9944";
// if no signer is set in the whole program, we need to give to Api a specific type instead of an associated type
// as during compilation the type needs to be defined.
let api = Api::<sr25519::Pair>::new(format!("ws://{}", url));
let meta = api.get_metadata();
println!("Metadata:\n {}", node_metadata::pretty_format(&meta).unwrap());
}
I get the following error:
unresolved import `substrate_primitives`
use of undeclared type or module `substrate_primitives`rustc(E0432)
main.rs(2, 5): use of undeclared type or module `substrate_primitives`
How do I import sr25519 so that I can use the following line in my code?
let api = Api::<sr25519::Pair>::new(format!("ws://{}", url));
The difference between tables under [dependencies] and the [dependencies.primitives] table is that the table for the primitives dependency is not inlined. You could also just inline the primitives dependency and put it under [dependencies] like that:
primitives = { git = "https://github.com/paritytech/substrate", rev = "3bf9540e72df5ecb3955845764dfee7dcdbb26b5", package = "substrate-primitives" }
The toml documentation can give you more details on tables and inline tables.
Regarding your problem. You cannot import the crate like that, because it is renamed to primitives. The package field specifies the real name of the dependency and the table name defines the new name which is used to import it inside your project. For details have a look at the cargo documentation.
Your import should therefore look like this: use primitives::sr25519;

Resources