2017-05-16 05:24:06 +00:00
|
|
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
|
|
|
|
|
|
|
use syn;
|
2017-05-23 06:19:14 +00:00
|
|
|
use quote::Tokens;
|
2017-05-16 05:24:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
2017-05-23 06:19:14 +00:00
|
|
|
let base = syn::Ident::from("_pyo3::PyObj");
|
2017-05-17 06:43:39 +00:00
|
|
|
|
|
|
|
match ast.body {
|
2017-05-23 06:19:14 +00:00
|
|
|
syn::Body::Struct(syn::VariantData::Struct(_)) => (),
|
|
|
|
_ => panic!("#[class] can only be used with notmal structs"),
|
2017-05-17 06:43:39 +00:00
|
|
|
}
|
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
let dummy_const = syn::Ident::new(format!("_IMPL_PYO3_CLS_{}", ast.ident));
|
2017-05-23 06:19:14 +00:00
|
|
|
let tokens = impl_class(&ast.ident, &base);
|
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
quote! {
|
|
|
|
#[feature(specialization)]
|
2017-05-18 21:46:29 +00:00
|
|
|
#[allow(non_upper_case_globals, unused_attributes,
|
|
|
|
unused_qualifications, unused_variables, non_camel_case_types)]
|
2017-05-16 05:24:06 +00:00
|
|
|
const #dummy_const: () = {
|
2017-05-18 18:15:06 +00:00
|
|
|
extern crate pyo3 as _pyo3;
|
2017-05-16 05:24:06 +00:00
|
|
|
use std;
|
|
|
|
|
|
|
|
#tokens
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-23 06:19:14 +00:00
|
|
|
fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
2017-05-18 23:57:39 +00:00
|
|
|
let cls_name = quote! { #cls }.as_str().to_string();
|
|
|
|
|
2017-05-17 06:43:39 +00:00
|
|
|
quote! {
|
2017-05-23 06:19:14 +00:00
|
|
|
|
2017-05-22 05:22:45 +00:00
|
|
|
impl _pyo3::class::typeob::PyTypeObjectInfo for #cls {
|
2017-05-23 06:19:14 +00:00
|
|
|
type Type = #cls;
|
|
|
|
|
2017-05-22 05:22:45 +00:00
|
|
|
#[inline]
|
|
|
|
fn size() -> usize {
|
|
|
|
Self::offset() + std::mem::size_of::<#cls>()
|
|
|
|
}
|
2017-05-17 06:43:39 +00:00
|
|
|
|
2017-05-22 05:22:45 +00:00
|
|
|
#[inline]
|
|
|
|
fn offset() -> usize {
|
|
|
|
let align = std::mem::align_of::<#cls>();
|
2017-05-23 06:19:14 +00:00
|
|
|
let bs = <#base as _pyo3::class::typeob::PyTypeObjectInfo>::size();
|
2017-05-17 06:43:39 +00:00
|
|
|
|
2017-05-22 05:22:45 +00:00
|
|
|
// round base_size up to next multiple of align
|
|
|
|
(bs + align - 1) / align * align
|
2017-05-17 06:43:39 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 23:57:39 +00:00
|
|
|
#[inline]
|
|
|
|
fn type_name() -> &'static str { #cls_name }
|
|
|
|
|
2017-05-17 06:43:39 +00:00
|
|
|
#[inline]
|
2017-05-19 04:35:08 +00:00
|
|
|
fn type_object() -> &'static mut _pyo3::ffi::PyTypeObject {
|
2017-05-18 18:15:06 +00:00
|
|
|
static mut TYPE_OBJECT: _pyo3::ffi::PyTypeObject = _pyo3::ffi::PyTypeObject_INIT;
|
2017-05-19 04:35:08 +00:00
|
|
|
unsafe { &mut TYPE_OBJECT }
|
2017-05-17 06:43:39 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
}
|