1+ use std:: ffi:: CString ;
2+ use std:: fmt;
3+ use log:: { Level , LevelFilter , Record } ;
4+ use crate :: { FormatFn , LogId } ;
5+
6+ /// Filter for android logger.
7+ #[ derive( Default ) ]
8+ pub struct Config {
9+ pub ( crate ) log_level : Option < LevelFilter > ,
10+ pub ( crate ) buf_id : Option < LogId > ,
11+ filter : Option < env_filter:: Filter > ,
12+ pub ( crate ) tag : Option < CString > ,
13+ pub ( crate ) custom_format : Option < FormatFn > ,
14+ }
15+
16+ impl fmt:: Debug for Config {
17+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
18+ f. debug_struct ( "Config" )
19+ . field ( "log_level" , & self . log_level )
20+ . field ( "buf_id" , & self . buf_id )
21+ . field ( "filter" , & self . filter )
22+ . field ( "tag" , & self . tag )
23+ . field (
24+ "custom_format" ,
25+ match & self . custom_format {
26+ Some ( _) => & "Some(_)" ,
27+ None => & "None" ,
28+ } ,
29+ )
30+ . finish ( )
31+ }
32+ }
33+
34+ impl Config {
35+ /// Changes the maximum log level.
36+ ///
37+ /// Note, that `Trace` is the maximum level, because it provides the
38+ /// maximum amount of detail in the emitted logs.
39+ ///
40+ /// If `Off` level is provided, then nothing is logged at all.
41+ ///
42+ /// [`log::max_level()`] is considered as the default level.
43+ pub fn with_max_level ( mut self , level : LevelFilter ) -> Self {
44+ self . log_level = Some ( level) ;
45+ self
46+ }
47+
48+ /// Changes the Android logging system buffer to be used.
49+ ///
50+ /// By default, logs are sent to the [`Main`] log. Other logging buffers may
51+ /// only be accessible to certain processes.
52+ ///
53+ /// [`Main`]: LogId::Main
54+ pub fn with_log_buffer ( mut self , buf_id : LogId ) -> Self {
55+ self . buf_id = Some ( buf_id) ;
56+ self
57+ }
58+
59+ pub ( crate ) fn filter_matches ( & self , record : & Record ) -> bool {
60+ if let Some ( ref filter) = self . filter {
61+ filter. matches ( record)
62+ } else {
63+ true
64+ }
65+ }
66+
67+ pub ( crate ) fn is_loggable ( & self , level : Level ) -> bool {
68+ // todo: consider __android_log_is_loggable.
69+ level <= self . log_level . unwrap_or_else ( log:: max_level)
70+ }
71+
72+ pub fn with_filter ( mut self , filter : env_filter:: Filter ) -> Self {
73+ self . filter = Some ( filter) ;
74+ self
75+ }
76+
77+ pub fn with_tag < S : Into < Vec < u8 > > > ( mut self , tag : S ) -> Self {
78+ self . tag = Some ( CString :: new ( tag) . expect ( "Can't convert tag to CString" ) ) ;
79+ self
80+ }
81+
82+ /// Sets the format function for formatting the log output.
83+ /// ```
84+ /// # use android_logger::Config;
85+ /// android_logger::init_once(
86+ /// Config::default()
87+ /// .with_max_level(log::LevelFilter::Trace)
88+ /// .format(|f, record| write!(f, "my_app: {}", record.args()))
89+ /// )
90+ /// ```
91+ pub fn format < F > ( mut self , format : F ) -> Self
92+ where
93+ F : Fn ( & mut dyn fmt:: Write , & Record ) -> fmt:: Result + Sync + Send + ' static ,
94+ {
95+ self . custom_format = Some ( Box :: new ( format) ) ;
96+ self
97+ }
98+ }
0 commit comments