1use std::fmt;
2use std::result::Result as StdResult;
3
4use luajit::{self as lua, Poppable, Pushable};
5use serde::{Deserialize, Serialize};
6use types::{
7 self as nvim,
8 conversion::{self, FromObject, ToObject},
9 Object,
10 TabHandle,
11};
12
13use crate::choose;
14use crate::ffi::tabpage::*;
15use crate::Result;
16use crate::SuperIterator;
17use crate::Window;
18
19#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
21pub struct TabPage(pub(crate) TabHandle);
22
23impl fmt::Debug for TabPage {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 f.debug_tuple("TabPage").field(&self.0).finish()
26 }
27}
28
29impl fmt::Display for TabPage {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 fmt::Debug::fmt(self, f)
32 }
33}
34
35impl<H: Into<TabHandle>> From<H> for TabPage {
36 fn from(handle: H) -> Self {
37 Self(handle.into())
38 }
39}
40
41impl From<TabPage> for Object {
42 fn from(tabpage: TabPage) -> Self {
43 tabpage.0.into()
44 }
45}
46
47impl Poppable for TabPage {
48 unsafe fn pop(
49 lstate: *mut lua::ffi::lua_State,
50 ) -> std::result::Result<Self, lua::Error> {
51 TabHandle::pop(lstate).map(Into::into)
52 }
53}
54
55impl Pushable for TabPage {
56 unsafe fn push(
57 self,
58 lstate: *mut lua::ffi::lua_State,
59 ) -> std::result::Result<std::ffi::c_int, lua::Error> {
60 self.0.push(lstate)
61 }
62}
63
64impl FromObject for TabPage {
65 fn from_object(obj: Object) -> StdResult<Self, conversion::Error> {
66 Ok(TabHandle::from_object(obj)?.into())
67 }
68}
69
70impl TabPage {
71 #[inline(always)]
73 pub fn current() -> Self {
74 crate::get_current_tabpage()
75 }
76
77 #[inline(always)]
79 pub fn handle(&self) -> i32 {
80 self.0
81 }
82
83 pub fn del_var(&mut self, name: &str) -> Result<()> {
89 let mut err = nvim::Error::new();
90 let name = nvim::String::from(name);
91 unsafe { nvim_tabpage_del_var(self.0, name.non_owning(), &mut err) };
92 choose!(err, ())
93 }
94
95 pub fn get_number(&self) -> Result<u32> {
101 let mut err = nvim::Error::new();
102 let number = unsafe { nvim_tabpage_get_number(self.0, &mut err) };
103 choose!(err, Ok(number.try_into().expect("always positive")))
104 }
105
106 pub fn get_var<Var>(&self, name: &str) -> Result<Var>
112 where
113 Var: FromObject,
114 {
115 let mut err = nvim::Error::new();
116 let name = nvim::String::from(name);
117 let obj = unsafe {
118 nvim_tabpage_get_var(
119 self.0,
120 name.non_owning(),
121 #[cfg(feature = "neovim-0-10")] types::arena(),
123 &mut err,
124 )
125 };
126 choose!(err, Ok(Var::from_object(obj)?))
127 }
128
129 pub fn get_win(&self) -> Result<Window> {
135 let mut err = nvim::Error::new();
136 let handle = unsafe { nvim_tabpage_get_win(self.0, &mut err) };
137 choose!(err, Ok(handle.into()))
138 }
139
140 pub fn is_valid(&self) -> bool {
146 unsafe { nvim_tabpage_is_valid(self.0) }
147 }
148
149 pub fn list_wins(&self) -> Result<impl SuperIterator<Window>> {
155 let mut err = nvim::Error::new();
156 let list = unsafe {
157 nvim_tabpage_list_wins(
158 self.0,
159 #[cfg(feature = "neovim-0-10")] types::arena(),
161 &mut err,
162 )
163 };
164 choose!(
165 err,
166 Ok({
167 list.into_iter().map(|obj| Window::from_object(obj).unwrap())
168 })
169 )
170 }
171
172 pub fn set_var<Var>(&mut self, name: &str, value: Var) -> Result<()>
178 where
179 Var: ToObject,
180 {
181 let mut err = nvim::Error::new();
182 let name = nvim::String::from(name);
183 unsafe {
184 nvim_tabpage_set_var(
185 self.0,
186 name.non_owning(),
187 value.to_object()?.non_owning(),
188 &mut err,
189 )
190 };
191 choose!(err, ())
192 }
193
194 #[cfg(feature = "neovim-0-10")] #[cfg_attr(
201 docsrs,
202 doc(cfg(any(feature = "neovim-0-10", feature = "neovim-nightly")))
203 )]
204 pub fn set_win(&mut self, win: &Window) -> Result<()> {
205 let mut err = nvim::Error::new();
206 unsafe { nvim_tabpage_set_win(self.0, win.0, &mut err) };
207 choose!(err, ())
208 }
209}