Bug 395192 - rust-qt-binding-generator: unable to compile multi-dimensional list
Summary: rust-qt-binding-generator: unable to compile multi-dimensional list
Status: RESOLVED FIXED
Alias: None
Product: rust-qt-binding-generator
Classification: Unmaintained
Component: general (show other bugs)
Version: unspecified
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: Jos van den Oever
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-09 22:40 UTC by carl
Modified: 2020-12-17 19:45 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
make log (7.90 KB, text/plain)
2018-06-09 22:40 UTC, carl
Details

Note You need to log in before you can comment on or make changes to this bug.
Description carl 2018-06-09 22:40:45 UTC
Created attachment 113181 [details]
make log

Hello, thank you for your work. I tried your libairy and I maybee come across a bug. 

I'm unable to build the rust binding for this binding.json


{
    "cppFile": "src/Binding.cpp",
    "rust": {
        "dir": "rust",
        "interfaceModule": "interface",
        "implementationModule": "implementation"
    },
    "objects": {
        "Sources": {
            "type": "List",
            "itemProperties": {
                "name": {
                    "type": "QString",
                    "rustByValue": true
                },
                "novel_list": {
                    "type": "Source"
                }
            }
        },
        "Source": {
            "type": "List",
            "itemProperties": {
                "title": {
                    "type": "QString",
                    "rustByValue": true
                },
                "chapter_list": {
                    "type": "Novel"
                }
            }
        },
        "Novel": {
            "type": "List",
            "itemProperties": {
                "index": {
                    "type": "quint32"
                },
                "title": {
                    "type": "QString",
                    "rustByValue": true
                },
                "content": {
                    "type": "QString",
                    "rustByValue": true
                }
            }
        }
    }
}


I'm able to compile my rust code, but the cpp code doesn't compile. I added the log in the attachment. But I don't think the error is from the binding, but it's more probably that the error come from the rust code. 

I was unable to derive from default, because emit is not implemented for interface::*Emitter. 

If you are interested in looking at the entire code, the code is hosted at https://gitlab.com/ognarb/webnovel-manager unter the rust branch

Thank you in advance 

Carl
Comment 1 Jos van den Oever 2018-06-10 22:23:21 UTC
The binding.json that you use has nested lists. That is currently not supported. The bug is that there is no error message for that.

You can nest a List or a Tree in an Object.

Could you remodel the structure into something where there is no nesting of Lists of Trees?
Comment 2 Jos van den Oever 2018-06-11 07:09:07 UTC
I recommend writing the binding like this:


    "objects": {
        "Novels": {
            "type": "Tree",
            "itemProperties": {
                "sourcesName": {
                    "type": "QString"
                },
                "sourceTitle": {
                    "type": "QString"
                },
                "novelIndex": {
                    "type": "quint32"
                },
                "novelTitle": {
                    "type": "QString"
                },
                "novelContent": {
                    "type": "QString"
                }
            }
        }
    }

Then you model it such that a novel has QAbstractItemModel::parent() which is the source and the source has a parent() which is the list of all sources.
Comment 3 carl 2018-10-31 22:53:24 UTC
Sorry for not giving any sign of live. I read your O.2 announcement and remembered that I posted this bug report a long time ago. I read you answers and I found your solution a bit 'hacky'. Is where at some point something in rust, cpp or qt that could forbid to use multidimensional list. I already saw that the new version don't need #[derive(clone)] anymore and with for example the new `impl trait` syntax in rust. Can't we not implement multidimensional list in this binding generator? I not yet very experimented with the model-view architecture, so maybe I forget something important. I'm looking at your code right now, and I will try to implement something.
Comment 4 Jos van den Oever 2018-11-01 08:02:24 UTC
The functionality that you want is possible, but quite some work.

The Model/View in Qt is based on QAbstractItemModel. The current code creates one QAbstractItemModel for a List or a Tree. Each node in the List or Tree has the same properties.

Your binding is for a List with a top level of nodes that have `name` and `novel_list`. Each `novel_list` of type `Source` has a list of items again: `chapter_list`. So your model is a tree but the nodes on each level have a different type. It is a clear and logical model from a data modelling point of view.

A logical Rust structure for this would be

struct Sources {
    name: String,
    novel_list: Vec<Source>,
}
struct Source {
    name: title: String,
    chapter_list: Vec<Novel>,
}
struct Novel {
    index: u32,
    title: String,
    content: String,
}

In Qt Model/View each node in a tree has an index and all nodes are basically the same. The delegates that render the nodes also treat all nodes the same. But each property can have a different role. If you want to show this model in a QTreeView or TreeView, you'd specify a different role or column for each property. So the role numbers and column numbers should be unique for the properties in the combination of Sources, Source and Novel. The solution I gave you does that. But it does not look as nice as the structure you want.

The current code could be expanded to interpret Sources, Source and Novel as belonging to one Tree. It would be very nice, but hard to implement such an addition to the code generator.

The solution I gave is also flawed in that I forgot to add `optional`:


    "objects": {
        "Novels": {
            "type": "Tree",
            "itemProperties": {
                "sourcesName": {
                    "type": "QString",
                    "optional": true
                },
                "sourceTitle": {
                    "type": "QString",
                    "optional": true
                },
                "novelIndex": {
                    "type": "quint32",
                    "optional": true
                },
                "novelTitle": {
                    "type": "QString",
                    "optional": true
                },
                "novelContent": {
                    "type": "QString",
                    "optional": true
                }
            }
        }
    }

This limitation in the generator is also present in Qt itself. If you write C++ code with QAbstractItemModel, you'd face the same issue that it expects each node in the tree to be the same.
Comment 5 carl 2018-11-01 09:46:30 UTC
Thank you for explanation. It's really helpful.