3333use crate :: bindings;
3434use crate :: connection:: HttpConnection ;
3535use crate :: error:: { Error , Result } ;
36+ use std:: env;
3637use std:: ffi:: { CStr , CString } ;
3738use std:: marker:: PhantomData ;
3839use std:: ptr;
@@ -83,6 +84,7 @@ pub enum IppValueTag {
8384 Charset ,
8485 Language ,
8586 MimeType ,
87+ DeleteAttr ,
8688}
8789
8890impl From < IppValueTag > for bindings:: ipp_tag_t {
@@ -99,6 +101,7 @@ impl From<IppValueTag> for bindings::ipp_tag_t {
99101 IppValueTag :: Charset => bindings:: ipp_tag_e_IPP_TAG_CHARSET,
100102 IppValueTag :: Language => bindings:: ipp_tag_e_IPP_TAG_LANGUAGE,
101103 IppValueTag :: MimeType => bindings:: ipp_tag_e_IPP_TAG_MIMETYPE,
104+ IppValueTag :: DeleteAttr => bindings:: ipp_tag_e_IPP_TAG_DELETEATTR,
102105 }
103106 }
104107}
@@ -248,6 +251,23 @@ impl IppRequest {
248251 } )
249252 }
250253
254+ /// Create a new IPP request from a raw operation code.
255+ /// This is useful for deprecated operations.
256+ pub fn new_raw ( op_code : i32 ) -> Result < Self > {
257+ let ipp = unsafe { bindings:: ippNewRequest ( op_code) } ;
258+
259+ if ipp. is_null ( ) {
260+ return Err ( Error :: UnsupportedFeature (
261+ "Failed to create IPP request" . to_string ( ) ,
262+ ) ) ;
263+ }
264+
265+ Ok ( IppRequest {
266+ ipp,
267+ _phantom : PhantomData ,
268+ } )
269+ }
270+
251271 /// Get the raw pointer to the ipp_t structure
252272 pub fn as_ptr ( & self ) -> * mut bindings:: _ipp_s {
253273 self . ipp
@@ -371,6 +391,35 @@ impl IppRequest {
371391 }
372392 }
373393
394+ /// Add standard IPP operation attributes:
395+ /// - attributes-charset = "utf-8"
396+ /// - attributes-natural-language = "en"
397+ /// - requesting-user-name = $USER (or "unknown")
398+ pub fn add_standard_attrs ( & mut self ) -> Result < ( ) > {
399+ let user = env:: var ( "USER" ) . unwrap_or_else ( |_| "unknown" . into ( ) ) ;
400+
401+ self . add_string (
402+ IppTag :: Operation ,
403+ IppValueTag :: Charset ,
404+ "attributes-charset" ,
405+ "utf-8" ,
406+ ) ?;
407+ self . add_string (
408+ IppTag :: Operation ,
409+ IppValueTag :: Language ,
410+ "attributes-natural-language" ,
411+ "en" ,
412+ ) ?;
413+ self . add_string (
414+ IppTag :: Operation ,
415+ IppValueTag :: Name ,
416+ "requesting-user-name" ,
417+ & user,
418+ ) ?;
419+
420+ Ok ( ( ) )
421+ }
422+
374423 /// Send this request and receive a response
375424 pub fn send ( & self , connection : & HttpConnection , resource : & str ) -> Result < IppResponse > {
376425 let resource_c = CString :: new ( resource) ?;
@@ -588,6 +637,13 @@ mod tests {
588637 assert ! ( result. is_ok( ) ) ;
589638 }
590639
640+ #[ test]
641+ fn test_add_standard_attrs ( ) {
642+ let mut request = IppRequest :: new ( IppOperation :: GetJobs ) . unwrap ( ) ;
643+ let result = request. add_standard_attrs ( ) ;
644+ assert ! ( result. is_ok( ) ) ;
645+ }
646+
591647 #[ test]
592648 fn test_ipp_status ( ) {
593649 assert ! ( IppStatus :: Ok . is_successful( ) ) ;
0 commit comments