Comments (10)
Right, so then you would do like this:
let tuple = (c.name, c.description, c.version, ...etc...);
let boxed = Box::new(tuple) as Box<dyn RefArg>;
...or like this, if the first version does not work for some reason:
let mut v: VecDeque<Box<dyn RefArg>> = VecDeque::new();
v.push(Box::new(c.name));
v.push(Box::new(c.description));
...etc...
let boxed = Box::new(v) as Box<dyn RefArg>;
implementing RefArg for your struct works too, but the above is probably a lot easier.
from dbus-rs.
Does this help:
let a = get_struct_of_strings_and_array_of_structs();
let b = Box::new(a) as Box<dyn RefArg>;
c.register_component(b);
If not, could you be more specific of what "a struct of strings and array of structs" mean, preferably by a code example?
from dbus-rs.
Thanks for the help. That's what I attempted to do but it didn't work. Here are the details:
From this Go code, this is the struct that's sent over DBus. It has strings and array of structs, and HashMap (I forgot to mention this one in the question). So, I did something similar in Rust:
pub struct Component {
pub name: String,
pub attachments: HashMap<String, arg::Variant<Box<dyn arg::RefArg>>>,
pub description: String,
pub version: String,
pub license: String,
pub author: String,
pub homepage: String,
pub exec: String,
pub textdomain: String,
pub engines: [EngineDesc; 1],
}
pub struct EngineDesc {
pub attachments: HashMap<String, arg::Variant<Box<dyn arg::RefArg>>>,
pub name: String,
pub longname: String,
pub description: String,
pub language: String,
pub license: String,
pub author: String,
pub icon: String,
pub layout: String,
pub rank: u32,
pub hotkeys: String,
pub symbol: String,
pub setup: String,
pub layout_variant: String,
pub layout_option: String,
pub version: String,
pub text_domain: String,
}
Then I did what you suggested:
let component = Component {
name: "org.freedesktop.IBus.Fcpinyin".to_owned(),
description: "Full Cloud Pinyin".to_owned(),
version: "0.1".to_owned(),
license: "MIT".to_owned(),
author: "Qingxiang Jia".to_owned(),
homepage: "https://github.com/qingxiang-jia/full-cloud-pinyin/".to_owned(),
exec: "".to_owned(),
textdomain: "full-cloud-pinyin".to_owned(),
attachments: HashMap::new(),
engines: [EngineDesc {
attachments: HashMap::new(),
name: "full-cloud-pinyin".to_owned(),
longname: "Full Cloud Pinyin".to_owned(),
description: "Full Cloud Pinyin".to_owned(),
language: "en".to_owned(),
license: "MIT".to_owned(),
author: "Qingxiang Jia".to_owned(),
icon: "/usr/share/icons/breeze/emblems/24@3x/emblem-checked.svg".to_owned(),
layout: "us".to_owned(),
rank: 0,
hotkeys: "".to_owned(),
symbol: "".to_owned(),
setup: "".to_owned(),
layout_option: "".to_owned(),
layout_variant: "".to_owned(),
version: "0.1".to_owned(),
text_domain: "full-cloud-pinyin".to_owned(),
}]
};
let componnet_variant = Box::new(component) as Box<dyn RefArg>;
match ibus.register_component(componnet_variant) {
Ok(()) => println!("Component registration successful!"),
Err(e) => {
println!("Failed to register component.");
display_debus_error(&e);
},
}
I got:
error[E0277]: the trait bound `manual::Component: RefArg` is not satisfied
--> src/main.rs:73:29
|
73 | let componnet_variant = Box::new(component) as Box<dyn RefArg>;
| ^^^^^^^^^^^^^^^^^^^ the trait `RefArg` is not implemented for `manual::Component`
|
= help: the following other types implement trait `RefArg`:
&'a T
&'a [T]
(A, B)
(A, B, C)
(A, B, C, D)
(A, B, C, D, E)
(A, B, C, D, E, F)
(A, B, C, D, E, F, G)
and 32 others
= note: required for the cast from `manual::Component` to the object type `dyn RefArg`
So I was wondering if it's not supported to have a struct behind a variant. I am also wondering if I need to implement RefArg
for my struct in order for it to be sent as a variant.
The source code of the above is here: qingxiang-jia/full-cloud-pinyin@9a2728a
from dbus-rs.
Thanks! Let me try it when I get home.
from dbus-rs.
Again, thanks for the help. But there's a few things I know I didn't get right (I think it's more about IBus, so maybe I should ask them than dbus-rs). I did your first suggested approach, basically putting the values into a tuple. There are some minor issues but in the end, the code compiles! However, the other end complained that I didn't pass in the right type (which is absolutely funny since they (IBus) defined it as a variant).
The actual error message is (again, it's more about IBus than dbus-rs):
DBus error: org.freedesktop.DBus.Error.Failed - The first argument should be an IBusComponent.
My guess is, with both approaches, we are passing in only the value, but not the "key". Here is what an IBusComponent should look like.
Minor: I mentioned there was a minor issue, that is, when passing the tuple, the compiler complained that the "array of EngineDesc" doesn't implement RefArg. Omitting that solves the problem.
The entire relevant code looks like the following:
qingxiang-jia/full-cloud-pinyin@469f41d
from dbus-rs.
The actual error message is (again, it's more about IBus than dbus-rs):
Yeah, I think at this point we need either better docs from IBus, or a working example in another language that we could translate to dbus-rs.
Could be that they're not expecting a struct but a PropMap, like:
let p = PropMap::new();
// fill propmap with data
let b = Box::new(p) as Box<dyn RefArg>;
register_component(Variant(b));
from dbus-rs.
That's possible. The example from the other language is from Go: https://github.com/sarim/goibus/blob/eb16b0161e3b2289ca6e2b8eb6beb3997e86920f/ibus/component.go#L10
Let me try that and if it doesn't, I will still close this issue. If I ever get some updates from IBus, I will update the closed issue.
from dbus-rs.
Hi I did some exploration and I now have the exact signature of the variant I should send.
It needs to be a variant of type (sa{sv}ssssssssavav)
, where the last av
has one element that is of type (sa{sv}ssssssssusssssss)
.
I was following the tuple approach but it doesn't work because (sa{sv}ssssssssusssssss)
is too long. I then tried the VecDeque<Box<dyn RefArg>>
approach you told me. But the problem is, for the a{sv}
part, I use HashMap<String, Box<dyn RefArg>>
, so basically:
let attachments: HashMap<String, Box<dyn RefArg>> = HashMap::new();
let mut v: VecDeque<Box<dyn RefArg>> = VecDeque::new();
v.push_back(Box::new("org.freedesktop.IBus.Fcpinyin".to_owned()));
v.push_back(Box::new(attachments));
...
But the compiler complains:
error[E0277]: the size for values of type `dyn RefArg` cannot be known at compilation time
--> src/main.rs:92:17
|
92 | v.push_back(Box::new(attachments));
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn RefArg`
= help: the trait `RefArg` is implemented for `HashMap<K, V, S>`
= note: required for `Box<dyn RefArg>` to implement `Arg`
= note: required for `HashMap<std::string::String, Box<dyn RefArg>>` to implement `RefArg`
= note: required for the cast from `HashMap<std::string::String, Box<dyn RefArg>>` to the object type `dyn RefArg`
When returning, I got another issue with:
error[E0605]: non-primitive cast: `VecDeque<Box<dyn RefArg>>` as `Box<dyn RefArg>`
--> src/main.rs:110:21
|
110 | return Box::new(v as Box<dyn RefArg>);
| ^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
In case it helps, the full code is here.
Thank you for the help!
from dbus-rs.
The following worked for me:
The function in question attempts to return:
Box<dyn RefArg>
Later I will wrap it into dbus::arg::Variant
by doing:
dbus::arg::Variant(Box::new(thing)) // thing is what the function returned.
Doing this gives me the second error in last post. The solution is to just wrap it into dbus::arg::Variant
first and return the Variant.
For the first error in the last post, the solution is to instead of declare attachments
as HashMap<String, dyn RefArg>
, declare it as HashMap<String, Variant<Box<dyn RefArg>>>
.
The full code is:
fn gen_engine_desc() -> dbus::arg::Variant<Box<dyn RefArg>> {
let attachments: HashMap<String, Variant<Box<dyn RefArg>>> = HashMap::new();
let mut v: VecDeque<Box<dyn RefArg>> = VecDeque::new();
v.push_back(Box::new("IBusEngineDesc".to_owned()));
v.push_back(Box::new(attachments));
...
v.push_back(Box::new("full-cloud-pinyin".to_owned()));
return dbus::arg::Variant(Box::new(v));
}
from dbus-rs.
@qingxiang-jia Glad you could solve it. For a{sv}
, PropMap is the way to go.
from dbus-rs.
Related Issues (20)
- async monitor? HOT 4
- monitor system bus without root privileges HOT 4
- dbus-codegen: When crossroads is enabled, no client-side code is generated HOT 3
- dbus-codegen: Add attribute to specify rust type for method arguments HOT 4
- Annotations on interfaces not shown in introspection
- Any way to set uid in dbus authentication? HOT 6
- How to ensure that libdbus-sys compiles with X11 for dbus-daemon autolaunch on build HOT 4
- register object of type X on dbus? HOT 3
- pkg config failed HOT 1
- Async signal match not working HOT 2
- `dbus-codegen-rust` produces `#[deprecated]` annotations on trait implementations HOT 1
- Yank rbus-rs package on crates.io HOT 1
- Generated code from an XML file that only contains properties does not compile with crossroads HOT 4
- Make new `dbus-codegen` release
- Recompilation of libdbus-sys triggered on every cargo build HOT 2
- "Path, Interface, or Method does not exist" on startup HOT 2
- Could `from_slice_unchecked` be made `const` for the string types?
- Derive Macros HOT 5
- dbus client improvement HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dbus-rs.