1 use std
::{fmt, hash, mem}
;
3 use thin_dst
::ErasedPtr
;
6 green
::{GreenNode, GreenToken, SyntaxKind}
,
10 pub(super) type GreenElement
= NodeOrToken
<GreenNode
, GreenToken
>;
11 pub(crate) type GreenElementRef
<'a
> = NodeOrToken
<&'a GreenNode
, &'a GreenToken
>;
14 pub(super) struct PackedGreenElement
{
18 impl From
<GreenNode
> for GreenElement
{
20 fn from(node
: GreenNode
) -> GreenElement
{
21 NodeOrToken
::Node(node
)
25 impl<'a
> From
<&'a GreenNode
> for GreenElementRef
<'a
> {
27 fn from(node
: &'a GreenNode
) -> GreenElementRef
<'a
> {
28 NodeOrToken
::Node(node
)
32 impl From
<GreenNode
> for PackedGreenElement
{
34 fn from(node
: GreenNode
) -> PackedGreenElement
{
35 unsafe { mem::transmute(node) }
39 impl From
<GreenToken
> for GreenElement
{
41 fn from(token
: GreenToken
) -> GreenElement
{
42 NodeOrToken
::Token(token
)
46 impl<'a
> From
<&'a GreenToken
> for GreenElementRef
<'a
> {
48 fn from(token
: &'a GreenToken
) -> GreenElementRef
<'a
> {
49 NodeOrToken
::Token(token
)
53 impl From
<GreenToken
> for PackedGreenElement
{
55 fn from(token
: GreenToken
) -> PackedGreenElement
{
56 unsafe { mem::transmute(token) }
61 /// Returns kind of this element.
63 pub fn kind(&self) -> SyntaxKind
{
67 /// Returns the length of the text covered by this element.
69 pub fn text_len(&self) -> TextSize
{
70 self.as_ref().text_len()
74 impl GreenElementRef
<'_
> {
75 /// Returns kind of this element.
77 pub fn kind(&self) -> SyntaxKind
{
79 NodeOrToken
::Node(it
) => it
.kind(),
80 NodeOrToken
::Token(it
) => it
.kind(),
84 /// Returns the length of the text covered by this element.
86 pub fn text_len(self) -> TextSize
{
88 NodeOrToken
::Node(it
) => it
.text_len(),
89 NodeOrToken
::Token(it
) => it
.text_len(),
94 impl From
<GreenElement
> for PackedGreenElement
{
95 fn from(element
: GreenElement
) -> Self {
97 NodeOrToken
::Node(node
) => node
.into(),
98 NodeOrToken
::Token(token
) => token
.into(),
103 impl From
<PackedGreenElement
> for GreenElement
{
104 fn from(element
: PackedGreenElement
) -> Self {
105 if element
.is_node() {
106 NodeOrToken
::Node(element
.into_node().unwrap())
108 NodeOrToken
::Token(element
.into_token().unwrap())
113 impl PackedGreenElement
{
114 fn is_node(&self) -> bool
{
115 self.ptr
.as_ptr() as usize & 1 == 0
118 pub(crate) fn as_node(&self) -> Option
<&GreenNode
> {
120 unsafe { Some(&*(&self.ptr as *const ErasedPtr as *const GreenNode)) }
126 pub(crate) fn into_node(self) -> Option
<GreenNode
> {
128 unsafe { Some(mem::transmute(self)) }
134 pub(crate) fn as_token(&self) -> Option
<&GreenToken
> {
136 unsafe { Some(&*(&self.ptr as *const ErasedPtr as *const GreenToken)) }
142 pub(crate) fn into_token(self) -> Option
<GreenToken
> {
144 unsafe { Some(mem::transmute(self)) }
150 pub(crate) fn as_ref(&self) -> GreenElementRef
<'_
> {
152 NodeOrToken
::Node(self.as_node().unwrap())
154 NodeOrToken
::Token(self.as_token().unwrap())
159 impl fmt
::Debug
for PackedGreenElement
{
160 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
162 self.as_node().unwrap().fmt(f
)
164 self.as_token().unwrap().fmt(f
)
169 impl Eq
for PackedGreenElement {}
170 impl PartialEq
for PackedGreenElement
{
171 fn eq(&self, other
: &Self) -> bool
{
172 self.as_node() == other
.as_node() && self.as_token() == other
.as_token()
176 impl hash
::Hash
for PackedGreenElement
{
177 fn hash
<H
>(&self, state
: &mut H
)
182 self.as_node().unwrap().hash(state
)
184 self.as_token().unwrap().hash(state
)
189 impl Drop
for PackedGreenElement
{
192 PackedGreenElement { ptr: self.ptr }
.into_node();
194 PackedGreenElement { ptr: self.ptr }
.into_token();
199 unsafe impl Send
for PackedGreenElement
205 unsafe impl Sync
for PackedGreenElement