[WIP] support casting between pgnodes#1048
[WIP] support casting between pgnodes#1048skyzh wants to merge 1 commit intopgcentralfoundation:developfrom
Conversation
Signed-off-by: Alex Chi <iskyzh@gmail.com>
|
Some things I'm not sure:
|
|
Do we need both And should that return a Result instead of an Option? Regarding the the blocklist you made, we identify those as a |
|
Thanks for the suggestion! I'm thinking of doing the code generation in another way: for PgCast, we should traverse on For the current blocklist, These are all subclass of TupleTable but doesn't have a corresponding node tag. Their casting is done by looking into
We can either use a blocklist or change implement PgCast only on those with a corresponding node tag. In this way we can do the casting code generation programmatically. Also the current implementation might be counter-intuitive in some cases. For example, Therefore, besides the |
It corresponds with |
workingjubilee
left a comment
There was a problem hiding this comment.
I would probably like us to have this but it needs some clarity of purpose.
| impl pg_sys::seal::Sealed for #struct_name {} | ||
| impl pg_sys::PgNode for #struct_name {} | ||
| impl pg_sys::PgNode for #struct_name { | ||
| const NODE_TAG: Option<NodeTag> = #node_tag; |
There was a problem hiding this comment.
We can't describe polymorphic types with a monomorphic tag like this.
| fn cast_from(pg_node: &A) -> Self { | ||
| Self::try_cast_from(pg_node).unwrap() | ||
| } |
There was a problem hiding this comment.
I agree with Eric, we should just make it always-fallible and ditch this.
| unsafe { | ||
| let node = std::mem::transmute::<_, &Node>(pg_node); | ||
| match B::NODE_TAG { | ||
| Some(tag) => { | ||
| if node.type_ == tag { | ||
| Some(std::mem::transmute::<_, &B>(node)) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
| None => None, | ||
| } | ||
| } |
There was a problem hiding this comment.
Hrmmm. What "directionality" of casting is this intended to handle? Upcasting? Downcasting? Something else? I feel we should support checked casting, for sure, instead of just making people do pointer-casts, but I don't feel confident about what this is "for", basically.
| let struct_name = &node_struct.struct_.ident; | ||
|
|
||
| let node_tag = if !block_list.contains(struct_name.to_string().as_str()) { | ||
| let node_tag = quote::format_ident!("NodeTag_T_{}", struct_name); |
There was a problem hiding this comment.
Sorry, I changed NodeTag to a real enum, so this would have to be
| let node_tag = quote::format_ident!("NodeTag_T_{}", struct_name); | |
| let node_tag = quote::format_ident!("NodeTag_T::{}", struct_name); |
| // Though these structs looks like a node, they don't seem to have a corresponding [`NodeTag`]. | ||
| // Also for `Node`, it doesn't have a node tag. | ||
| let block_list = [ | ||
| "Node", |
There was a problem hiding this comment.
Why block Node, exactly?
|
The way forward is probably having each Node type implement a trait that has a function that can be called to determine if the cast is valid. |
This is slightly off, my apologies. It's more like an abstract Node type, which means that other Nodes can have it as their superclass. |
No description provided.